Zulip Chat Archive

Stream: mathlib4

Topic: make `tfae` tactics a block tactic?


Thomas Murrills (Feb 04 2023 at 20:40):

tl;dr I'd like to combine tfae_have and tfae_finish (at least behind the scenes) into a single block tactic instead of two disconnected tactics.

Currently (in mathlib3) the tfae tactics work by having tfae_finish look through all the hypotheses in the context, not just those generated by tfae_have. Is this really necessary (or a good idea)?

In all the examples I’ve looked at so far we use tfae_have to introduce every assumption (so we don’t actually need to use any other assumptions in the context that tfae_finish gathers). (Plus naively it seems like it might mean a lot of defeq checks between types in assumptions and parts of the goal, since we can’t keep track of which assumption connects which two tfae goals.)

We could simplify things if tfae_have and tfae_finish were combined into a single “block tactic” like e.g.

tfae
| 1  2 := by 
| 2  3 := by 
| 3  1 := by 

Also tbh (and perhaps most practically important) a block-like tactic would be easier for me to implement, at least by my current assessment. :sweat_smile:

(Actually we could even keep the lean4-ified version of the old syntax and just make it magically a block tactic:

tfae_have : 1  2 := by 
tfae_have : 2  3 := by 
tfae_have : 3  1 := by 
tfae_finish

where behind the scenes this is all one big syntax node.)

My question here isn’t about the syntax; it’s just about whether it would be okay to change the nature of these tactics to be more of a “single tactic” than separately-called ones.

That is, as long as I can verify that mathlib doesn’t rely on tfae_finish being able to access the full context, and that we never “interrupt” a sequence of tfae_haves with some other tactic for some reason (which would also make it non-block-able).

Mario Carneiro (Feb 04 2023 at 21:38):

I think it would be best to design the tfae_have and tfae_finish tactics with roughly the behavior they have in lean 3, and then add a tfae block tactic and use mathport to translate to the block tactic form when possible, or use a linter which detects the syntactic pattern and suggests the block tactic

Mario Carneiro (Feb 04 2023 at 21:39):

Perhaps it should be spelled tfae for the current tfae_finish, and tfae with for the block tactic, for consistency with the lean 4 cases tactic

Yury G. Kudryashov (Feb 04 2023 at 21:43):

BTW, is it hard to fix mathport so that it doesn't generate very long error messages for proofs that use tfae?

Yury G. Kudryashov (Feb 04 2023 at 21:44):

https://github.com/leanprover-community/mathlib4/pull/2052/files#diff-2120274c41c22080464ed7c284ab18bb00a8b6c2e202089ba2c2a605c77f455cR1581

Mario Carneiro (Feb 04 2023 at 21:45):

geez, why aren't people reporting these things

Mario Carneiro (Feb 04 2023 at 21:45):

that kind of message is always a bug in mathport

Yury G. Kudryashov (Feb 04 2023 at 21:45):

We started porting files with tfae not so long ago. Deleting 100 lines is easy.

Mario Carneiro (Feb 04 2023 at 21:46):

yes I know that's what I mean by "why aren't people reporting these things"

Mario Carneiro (Feb 04 2023 at 21:46):

when you see a bug, report it, don't just work around

Mario Carneiro (Feb 04 2023 at 21:47):

the output syntax after the 100 lines is also garbage

Thomas Murrills (Feb 04 2023 at 21:53):

Mario Carneiro said:

I think it would be best to design the tfae_have and tfae_finish tactics with roughly the behavior they have in lean 3, and then add a tfae block tactic and use mathport to translate to the block tactic form when possible, or use a linter which detects the syntactic pattern and suggests the block tactic

sounds reasonable! which should I do first?

the block version is probably easier for me to implement—I can just build the proof directly instead of doing a search through the context. Aside from a test I think it covers everything in mathlib (that is, all uses of tfae_finish are immediately preceded by all necessary tfae_haves) and so would be sufficient for porting, if mathport could handle the change (I can double check this if necessary). but idk if it’s important to have mathlib behavior first

Mario Carneiro (Feb 04 2023 at 22:11):

mathlib behavior first is definitely important

Mario Carneiro (Feb 04 2023 at 22:11):

not to mention that with my proposal you would need the non-block structured version anyway

Mario Carneiro (Feb 04 2023 at 22:12):

@Yury G. Kudryashov tfae construction is fixed on mathport master

Yury G. Kudryashov (Feb 04 2023 at 22:14):

IMHO, "rewrite in a block structure" is a simple fix. There are only 33 calls to tfae_finish in mathlib.

Mario Carneiro (Feb 04 2023 at 22:16):

I'm thinking more along the lines of what we want to have eventually, plus preserving compatibility

Mario Carneiro (Feb 04 2023 at 22:17):

For sure we can encourage block structure, but there are use cases that prefer to avoid block structure, and code outside of mathlib as well which will be translated by mathport after the port

Mario Carneiro (Feb 04 2023 at 22:17):

it's the same as the situation with cases vs cases'

Mario Carneiro (Feb 04 2023 at 22:19):

At least, a block structured version of tfae should allow the blocks to be ?_ and filled after the tactic, like cases / induction

Thomas Murrills (Feb 04 2023 at 22:24):

gotcha, I just thought that if we wanted to speed up the porting that’s happening immediately we’d want a rudimentary (block) version that handled all porting cases, and then we could expand to handle backwards compatibility, ?_ cases, and non-mathlib files like, over the next couple weeks 🙃

Mario Carneiro (Feb 04 2023 at 22:30):

I think it will be simpler not to refactor this now

Thomas Murrills (Feb 04 2023 at 22:31):

? what’s the refactor?

Mario Carneiro (Feb 04 2023 at 22:31):

making tfae a block tactic

Mario Carneiro (Feb 04 2023 at 22:31):

the mathlib implementation has two tactics with specified semantics

Mario Carneiro (Feb 04 2023 at 22:31):

this is already implemented in mathport

Thomas Murrills (Feb 04 2023 at 22:32):

oh you mean so that mathport doesn’t have to change?

Thomas Murrills (Feb 04 2023 at 22:32):

because all instances of use are basically already in block form, just not internally

Mario Carneiro (Feb 04 2023 at 22:32):

changing mathport can be done, but I don't think removing tfae_have and tfae_finish entirely is an option

Mario Carneiro (Feb 04 2023 at 22:32):

we can add another tactic but that's not simplifying things

Mario Carneiro (Feb 04 2023 at 22:33):

both of these tactics have simple implementations, please don't complicate this

Mario Carneiro (Feb 04 2023 at 22:34):

refactoring stuff to use a block tactic is easy to do later

Thomas Murrills (Feb 04 2023 at 22:34):

well, one uses scc which I was hoping to avoid re-implementing for v1

Yury G. Kudryashov (Feb 04 2023 at 22:34):

If we port all files that have tfae before the tactic is implemented, then compatibility won't be a problem.

Mario Carneiro (Feb 04 2023 at 22:34):

sure, as I said you don't need that you can use solve_by_elim

Mario Carneiro (Feb 04 2023 at 22:35):

Yury G. Kudryashov said:

If we port all files that have tfae before the tactic is implemented, then compatibility won't be a problem.

unless tfae is used outside mathlib

Mario Carneiro (Feb 04 2023 at 22:35):

and even then, what will we use for cases where there are tactics in the middle etc

Thomas Murrills (Feb 04 2023 at 22:36):

just writing solve_by_elim instead of tfae_finish will work? I’m not really familiar with solve_by_elim, I guess I’ll look it up

Mario Carneiro (Feb 04 2023 at 22:36):

tfae_finish should be implementable as solve_by_elim with some settings

Thomas Murrills (Feb 04 2023 at 22:37):

Ok, that sure is easier then lol

Thomas Murrills (Feb 05 2023 at 12:34):

Ok, basic (mathlib-parity) versions of tfae_have and tfae_finish now exist: !4#2062 (All that's missing from this very basic version is the copyright header and the docstrings—and, of course, more tests, to make sure that they do actually function as intended)

Thomas Murrills (Feb 05 2023 at 13:18):

(docs are done too now! It's just that copyright header, and I'm not sure how that works exactly :grimacing: Most code is original, but I did take inspiration from a couple existing definitions, such as mathlib's have, and of course the whole thing is a re-implementation of something that existed already...I welcome anyone who knows how to sort that out correctly either telling me "what counts" in principle or, if it's easier simply telling me exactly what the header should be. :sweat_smile: (In this case also feel free to commit it if it speeds things up, as I'll be out of commission for several hours now.))

EDIT: maybe the lint-necessary docs aren’t done, actually, I’m not sure—but the main user-facing docs that people will see on hover are done.

Mario Carneiro (Feb 05 2023 at 21:26):

Copy the mathlib3 tfae header and add yourself as author

Thomas Murrills (Feb 05 2023 at 21:37):

If I adapted a function from another file (Have, mathlib version) do I add all of those authors as authors to this file?

Mario Carneiro (Feb 05 2023 at 22:02):

no

Thomas Murrills (Feb 05 2023 at 22:13):

alright, we have :check: for v1!

all that we might want to do is rename tfae_finish to tfae, as you mentioned, @Mario Carneiro. Should I go ahead and do that? We just need an #align tfae_finish tfae, right?

EDIT: I re-read what you wrote and I think you might mean something else, right? use tfae(block tactic) to mean just tfae_finish, and tfae with ... for when cases are necessary?

Mario Carneiro (Feb 05 2023 at 22:45):

no #align is not relevant for tactics. This change would have to be done directly in mathport

Thomas Murrills (Feb 05 2023 at 22:49):

I see. so do you think we should we change tfae_finish to tfae in this PR or not?

Jireh Loreaux (Feb 05 2023 at 22:51):

Don't rename now in any case. That can always be done later if it's desired.


Last updated: Dec 20 2023 at 11:08 UTC