Mercurial > cpdt > repo
comparison src/Large.v @ 241:cb3f3ef9d5bb
slow
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Wed, 09 Dec 2009 11:36:37 -0500 |
parents | b28c6e6eca0c |
children | 5a32784e30f3 |
comparison
equal
deleted
inserted
replaced
240:b28c6e6eca0c | 241:cb3f3ef9d5bb |
---|---|
516 | 516 |
517 Abort. | 517 Abort. |
518 | 518 |
519 (** printing * $\times$ *) | 519 (** printing * $\times$ *) |
520 | 520 |
521 (** Sometimes a change to a development has undesirable performance consequences, even if it does not prevent any old proof scripts from completing. If the performance consequences are severe enough, the proof scripts can be considered broken for practical purposes. | |
522 | |
523 Here is one example of a performance surprise. *) | |
524 | |
521 Section slow. | 525 Section slow. |
522 Hint Resolve trans_eq. | 526 Hint Resolve trans_eq. |
527 | |
528 (** The central element of the problem is the addition of transitivity as a hint. With transitivity available, it is easy for proof search to wind up exploring exponential search spaces. We also add a few other arbitrary variables and hypotheses, designed to lead to trouble later. *) | |
523 | 529 |
524 Variable A : Set. | 530 Variable A : Set. |
525 Variables P Q R S : A -> A -> Prop. | 531 Variables P Q R S : A -> A -> Prop. |
526 Variable f : A -> A. | 532 Variable f : A -> A. |
527 | 533 |
528 Hypothesis H1 : forall x y, P x y -> Q x y -> R x y -> f x = f y. | 534 Hypothesis H1 : forall x y, P x y -> Q x y -> R x y -> f x = f y. |
529 Hypothesis H2 : forall x y, S x y -> R x y. | 535 Hypothesis H2 : forall x y, S x y -> R x y. |
530 | 536 |
537 (** We prove a simple lemma very quickly, using the [Time] command to measure exactly how quickly. *) | |
538 | |
531 Lemma slow : forall x y, P x y -> Q x y -> S x y -> f x = f y. | 539 Lemma slow : forall x y, P x y -> Q x y -> S x y -> f x = f y. |
532 debug eauto. | 540 Time eauto 6. |
541 (** [[ | |
542 Finished transaction in 0. secs (0.068004u,0.s) | |
543 ]] *) | |
544 | |
533 Qed. | 545 Qed. |
534 | 546 |
547 (** Now we add a different hypothesis, which is innocent enough; in fact, it is even provable as a theorem. *) | |
548 | |
535 Hypothesis H3 : forall x y, x = y -> f x = f y. | 549 Hypothesis H3 : forall x y, x = y -> f x = f y. |
536 | 550 |
537 Lemma slow' : forall x y, P x y -> Q x y -> S x y -> f x = f y. | 551 Lemma slow' : forall x y, P x y -> Q x y -> S x y -> f x = f y. |
538 debug eauto. | 552 Time eauto 6. |
553 (** [[ | |
554 Finished transaction in 2. secs (1.264079u,0.s) | |
555 | |
556 ]] | |
557 | |
558 Why has the search time gone up so much? The [info] command is not much help, since it only shows the result of search, not all of the paths that turned out to be worthless. *) | |
559 | |
560 Restart. | |
561 info eauto 6. | |
562 (** [[ | |
563 == intro x; intro y; intro H; intro H0; intro H4; | |
564 simple eapply trans_eq. | |
565 simple apply refl_equal. | |
566 | |
567 simple eapply trans_eq. | |
568 simple apply refl_equal. | |
569 | |
570 simple eapply trans_eq. | |
571 simple apply refl_equal. | |
572 | |
573 simple apply H1. | |
574 eexact H. | |
575 | |
576 eexact H0. | |
577 | |
578 simple apply H2; eexact H4. | |
579 | |
580 ]] | |
581 | |
582 This output does not tell us why proof search takes so long, but it does provide a clue that would be useful if we had forgotten that we added transitivity as a hint. The [eauto] tactic is applying depth-first search, and the proof script where the real action is ends up buried inside a chain of pointless invocations of transitivity, where each invocation uses reflexivity to discharge one subgoal. Each increment to the depth argument to [eauto] adds another silly use of transitivity. This wasted proof effort only adds linear time overhead, as long as proof search never makes false steps. No false steps were made before we added the new hypothesis, but somehow the addition made possible a new faulty path. To understand which paths we enabled, we can use the [debug] command. *) | |
583 | |
584 Restart. | |
585 debug eauto 6. | |
586 | |
587 (** The output is a large proof tree. The beginning of the tree is enough to reveal what is happening: | |
588 | |
589 [[ | |
590 1 depth=6 | |
591 1.1 depth=6 intro | |
592 1.1.1 depth=6 intro | |
593 1.1.1.1 depth=6 intro | |
594 1.1.1.1.1 depth=6 intro | |
595 1.1.1.1.1.1 depth=6 intro | |
596 1.1.1.1.1.1.1 depth=5 apply H3 | |
597 1.1.1.1.1.1.1.1 depth=4 eapply trans_eq | |
598 1.1.1.1.1.1.1.1.1 depth=4 apply refl_equal | |
599 1.1.1.1.1.1.1.1.1.1 depth=3 eapply trans_eq | |
600 1.1.1.1.1.1.1.1.1.1.1 depth=3 apply refl_equal | |
601 1.1.1.1.1.1.1.1.1.1.1.1 depth=2 eapply trans_eq | |
602 1.1.1.1.1.1.1.1.1.1.1.1.1 depth=2 apply refl_equal | |
603 1.1.1.1.1.1.1.1.1.1.1.1.1.1 depth=1 eapply trans_eq | |
604 1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 depth=1 apply refl_equal | |
605 1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 depth=0 eapply trans_eq | |
606 1.1.1.1.1.1.1.1.1.1.1.1.1.1.2 depth=1 apply sym_eq ; trivial | |
607 1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1 depth=0 eapply trans_eq | |
608 1.1.1.1.1.1.1.1.1.1.1.1.1.1.3 depth=0 eapply trans_eq | |
609 1.1.1.1.1.1.1.1.1.1.1.1.2 depth=2 apply sym_eq ; trivial | |
610 1.1.1.1.1.1.1.1.1.1.1.1.2.1 depth=1 eapply trans_eq | |
611 1.1.1.1.1.1.1.1.1.1.1.1.2.1.1 depth=1 apply refl_equal | |
612 1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1 depth=0 eapply trans_eq | |
613 1.1.1.1.1.1.1.1.1.1.1.1.2.1.2 depth=1 apply sym_eq ; trivial | |
614 1.1.1.1.1.1.1.1.1.1.1.1.2.1.2.1 depth=0 eapply trans_eq | |
615 1.1.1.1.1.1.1.1.1.1.1.1.2.1.3 depth=0 eapply trans_eq | |
616 | |
617 ]] | |
618 | |
619 The first choice [eauto] makes is to apply [H3], since [H3] has the fewest hypotheses of all of the hypotheses and hints that match. However, it turns out that the single hypothesis generated is unprovable. That does not stop [eauto] from trying to prove it with an exponentially-sized tree of applications of transitivity, reflexivity, and symmetry of equality. It is the children of the initial [apply H3] that account for all of the noticeable time in proof execution. In a more realistic development, we might use this output of [info] to realize that adding transitivity as a hint was a bad idea. *) | |
620 | |
539 Qed. | 621 Qed. |
540 End slow. | 622 End slow. |
623 | |
624 (** It is also easy to end up with a proof script that uses too much memory. As tactics run, they avoid generating proof terms, since serious proof search will consider many possible avenues, and we do not want to built proof terms for subproofs that end up unused. Instead, tactic execution maintains %\textit{%#<i>#thunks#</i>#%}% (suspended computations, represented with closures), such that a tactic's proof-producing thunk is only executed when we run [Qed]. These thunks can use up large amounts of space, such that a proof script exhausts available memory, even when we know that we could have used much less memory by forcing some thunks earlier. | |
625 | |
626 The [abstract] tactical helps us force thunks by proving some subgoals as their own lemmas. For instance, a proof [induction x; crush] can in many cases be made to use significantly less peak memory by changing it to [induction x; abstract crush]. The main limitation of [abstract] is that it can only be applied to subgoals that are proved completely, with no undetermined unification variables remaining. Still, many large automated proofs can realize vast memory savings via [abstract]. *) | |
541 | 627 |
542 | 628 |
543 (** * Modules *) | 629 (** * Modules *) |
544 | 630 |
545 Module Type GROUP. | 631 Module Type GROUP. |