Skip to content

[Merged by Bors] - fix: make casesm and constructorm fail if no matches are found#1552

Closed
dwrensha wants to merge 1 commit intomasterfrom
casesm-match-fail
Closed

[Merged by Bors] - fix: make casesm and constructorm fail if no matches are found#1552
dwrensha wants to merge 1 commit intomasterfrom
casesm-match-fail

Conversation

@dwrensha
Copy link
Copy Markdown
Member

The main thing I want to fix here is that tauto on master currently never fails quickly. E.g. this takes many seconds to fail:

example (p : Prop) : p := by tauto

The reason is that the final step of tauto repeats until it sees a failure, and constructorMatching never fails, so we end up going until a timeout is hit.

allGoals (iterateUntilFailure
(evalTactic (← `(tactic| rfl)) <|>
evalTactic (← `(tactic| solve_by_elim)) <|>
liftMetaTactic (constructorMatching · finishingConstructorMatcher)))

When I originally wrote this code, I had expected that constructorMatching would fail when it finds no match, similar to how the mathlib3 tactic constructor_matching fails when it finds no match.

To fix the problem, this PR adds a throwOnNoMatch optional parameter to the casesMatching and constructorMatching functions, with default value set to !recursive. This means that the casesm and constructorm tactics will fail on no match, but the casesm* and constructorm* tactics will succeed on no match. That corresponds exactly to how the analogous tactics work in mathlib3.

According to some zulip discussion, other folks agree that the mathlib3 behavior was better.

This PR also explicitly sets (throwOnNoMatch := false) on the other calls to constructorMatching and casesMatching in tautoCore, because in those cases we don't want a failure. Technically, to exactly match the mathlib3 behavior there, we should be setting (recursive := true), as I do in #1507, but if I do that here without the other performance fixes in that PR, then the proof of Preorder.toCircularPreorder gets pushed over the default maxHeartbeats timeout.

@dwrensha dwrensha added the t-meta Tactics, attributes or user commands label Jan 13, 2023

instance : LawfulFunctor (Sum.{v, u} e) := by refine' { .. } <;> intros <;> casesm Sum _ _ <;> rfl
instance : LawfulFunctor (Sum.{v, u} e) := by
refine' { .. } <;> intros <;> (try casesm Sum _ _) <;> rfl
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The casesm Sum _ _ succeeds on some subgoals and fails on some others, so we need to wrap it in a try.

@digama0
Copy link
Copy Markdown
Member

digama0 commented Jan 17, 2023

bors r+

@github-actions github-actions bot added ready-to-merge This PR has been sent to bors. and removed awaiting-review labels Jan 17, 2023
bors bot pushed a commit that referenced this pull request Jan 17, 2023
The main thing I want to fix here is that `tauto` on master currently never fails *quickly*. E.g. this takes many seconds to fail:
```lean
example (p : Prop) : p := by tauto
```
The reason is that the final step of `tauto` repeats until it sees a failure, and `constructorMatching` never fails, so we end up going until a timeout is hit.
https://github.com/leanprover-community/mathlib4/blob/e78a2694fd2c5b00c16b4139f4a45faa17d2718d/Mathlib/Tactic/Tauto.lean#L150-L153

When I originally wrote this code, I had expected that `constructorMatching` would fail when it finds no match, similar to how the mathlib3 tactic `constructor_matching` fails when it finds no match.

To fix the problem, this PR adds a `throwOnNoMatch` optional parameter to the `casesMatching` and `constructorMatching` functions, with default value set to `!recursive`. This means that the `casesm` and `constructorm` tactics will fail on no match, but the `casesm*` and `constructorm*` tactics will succeed on no match. That corresponds exactly to how the analogous tactics work in mathlib3.

According to some [zulip discussion](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/casesm.20.2F.20constructorm.20on.20no.20match.3A.20error.20or.20not.3F), other folks agree that the mathlib3 behavior was better.

This PR also explicitly sets `(throwOnNoMatch := false)` on the other calls to `constructorMatching` and `casesMatching` in `tautoCore`, because in those cases we don't want a failure. Technically, to exactly match the mathlib3 behavior there, we should be setting `(recursive := true)`, as I do in #1507, but if I do that here without the other performance fixes in that PR, then the proof of `Preorder.toCircularPreorder` gets pushed over the default `maxHeartbeats` timeout.
@bors
Copy link
Copy Markdown

bors bot commented Jan 17, 2023

Pull request successfully merged into master.

Build succeeded:

@bors bors bot changed the title fix: make casesm and constructorm fail if no matches are found [Merged by Bors] - fix: make casesm and constructorm fail if no matches are found Jan 17, 2023
@bors bors bot closed this Jan 17, 2023
@bors bors bot deleted the casesm-match-fail branch January 17, 2023 03:10
jcommelin pushed a commit that referenced this pull request Jan 23, 2023
The main thing I want to fix here is that `tauto` on master currently never fails *quickly*. E.g. this takes many seconds to fail:
```lean
example (p : Prop) : p := by tauto
```
The reason is that the final step of `tauto` repeats until it sees a failure, and `constructorMatching` never fails, so we end up going until a timeout is hit.
https://github.com/leanprover-community/mathlib4/blob/e78a2694fd2c5b00c16b4139f4a45faa17d2718d/Mathlib/Tactic/Tauto.lean#L150-L153

When I originally wrote this code, I had expected that `constructorMatching` would fail when it finds no match, similar to how the mathlib3 tactic `constructor_matching` fails when it finds no match.

To fix the problem, this PR adds a `throwOnNoMatch` optional parameter to the `casesMatching` and `constructorMatching` functions, with default value set to `!recursive`. This means that the `casesm` and `constructorm` tactics will fail on no match, but the `casesm*` and `constructorm*` tactics will succeed on no match. That corresponds exactly to how the analogous tactics work in mathlib3.

According to some [zulip discussion](https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/casesm.20.2F.20constructorm.20on.20no.20match.3A.20error.20or.20not.3F), other folks agree that the mathlib3 behavior was better.

This PR also explicitly sets `(throwOnNoMatch := false)` on the other calls to `constructorMatching` and `casesMatching` in `tautoCore`, because in those cases we don't want a failure. Technically, to exactly match the mathlib3 behavior there, we should be setting `(recursive := true)`, as I do in #1507, but if I do that here without the other performance fixes in that PR, then the proof of `Preorder.toCircularPreorder` gets pushed over the default `maxHeartbeats` timeout.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge This PR has been sent to bors. t-meta Tactics, attributes or user commands

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants