-
Notifications
You must be signed in to change notification settings - Fork 246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewriting Tactic #1658
Rewriting Tactic #1658
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks awesome, thank you so much @TOTBWF! Added some comments.
I would be interested to see how it stacks up against #1158 which appears to be a bit dead in the water. In theory your solution is much nicer as it doesn't require you to manually point out where to apply cong
. It would be great if you could try it out on the test cases in #1158 (comment). Not all of them are relevant though, as they assume the tactic automatically applies sym
as well.
So the big thing that is missing is a README file, under README.Tactic.Rewrite
explaining how to use it. It also doubles as a test file, to prevent regressions. You could add the test cases there?
Also I'm wondering slightly about the name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The level of commenting in this code is exemplary. I need to up my own game to match this!
Given that it's applying That being said the missing argument in |
I like |
Working through some of the test cases, I've stumbled across some really weird behaviour: lit-test₁ : 40 + 2 ≡ 42
lit-test₁ = cong! refl This produces unsolved metas: lit-test₁ : 40 + 2 ≡ 42
lit-test₁ = cong (λ ϕ → ϕ) refl It appears that Agda is checking the types of the arguments before quoting them and passing them into the macro. This can be confirmed by adding a dummy argument to lit-test₁ : 40 + 2 ≡ 42
lit-test₁ = cong! (refl {x = "uh-oh"}) Trying this out with the EDIT: Of course immediately after posting this I figured it out. The trick is to not quote the equality proof in question. |
You mean you intend to change the type of |
So naive anti-unification is a bit too naive in a couple of cases. For instance, consider rewriting with |
This tactic is clearly very valuable as it stands, and I think it would be a shame to let perfection be the enemy of the good here. I'm exceptionally excited to start using it in my proofs. |
Agreed! @TOTBWF if you add the README and the CHANGELOG entries I'll merge it in and then afterwards we can work on improving it if people are still keen. |
Cool! I've added the README file and fixed some minor issues. I'll stew a bit over what the best strategy for a more advanced version would be; I have some rough ideas, but nothing too concrete yet. |
Meant to comment on this earlier. Of course I agree with others that it is already valuable as it stands. What I would like to see is a bit of documentation about its limitations -- roughly so that people don't continually report known limitations and/or try to use it for what it is known not to work on. I'm unsurprised that just anti-unification has limits. There's a reason things like AC and ACI-unification exist as separate items from just unification. You probably want to do a sort of anti-unification-modulo-theory. [No, this doesn't exist yet. I'm just giving it an obvious name.] |
There's a short blurb in the README file that describes the situations it is likely to fail in, but ideally someone can come up with a smarter algorithm :) |
Patch Description
This PR adds a new tactic
rw
, which is a simple equality rewriting tactic, intended to be used in equational reasoning blocks.Motivation
When performing large equational reasoning proofs, it's extremely common to find yourself constructing sophisticated lambdas to pass into
cong
. This is extremely tedious, and can bog down large proofs in piles of verbose boilerplate. Normally one would userewrite
to avoid having to write out these complicatedcong
expressions, but this can obscure the proof, and is often impossible (IE: when usingRelation.Binary.Reasoning.Preorder
).Implementation
We solve this problem by introducing a new tactic,
rw
, that gives us a similar level succinctness asrewrite
, but without it's restrictions. It operates by inferring the type of the goal, anti-unifying both ends of the equality, and then using that to construct the lambda argument tocong
. This allows us to drastically reduce boilerplate; for instancebecomes
This also plays nicely with
C-c C-m
, which allows for the quick generation of boilerplate for those who are hesitant of having tactics in the final source.Notes
When the
rw
tactic is used in a hole, it doesn't report it's type properly whenC-c C-.
is used, and instead reports a metavariable.C-c C-r
works fine though, so it's a minor quirk at worst.