Zulip Chat Archive

Stream: mathlib4

Topic: Renaming `split`


Gabriel Ebner (Oct 14 2021 at 08:46):

As you've probably noticed, core Lean has also defined a split tactic now. Of course, the new tactic does something completely different---split now seems to be a generalization of split_ifs.

In other words, we should rename the split (≈ constructor) tactic. Any suggestions for a new name?

Johan Commelin (Oct 14 2021 at 08:48):

First suggestions by a random thesaurus: rip, rent, snag, tear,

Mario Carneiro (Oct 14 2021 at 08:49):

intro

Johan Commelin (Oct 14 2021 at 08:49):

But split worked on the goal.

Mario Carneiro (Oct 14 2021 at 08:49):

intro also works on the goal

Johan Commelin (Oct 14 2021 at 08:50):

I think if you have P ∧ Q as goal, using intro to split it into pieces is weird from a semantic point of view.

Mario Carneiro (Oct 14 2021 at 08:50):

why is that? You are literally applying and.intro

Mario Carneiro (Oct 14 2021 at 08:51):

alternatively, we could just lean into constructor if the name isn't taken

Mario Carneiro (Oct 14 2021 at 08:51):

mk?

Johan Commelin (Oct 14 2021 at 08:52):

I think intro is a synonym for assume in my mind. Maybe I should decouple that.

Johan Commelin (Oct 14 2021 at 08:53):

destruct?

Johan Commelin (Oct 14 2021 at 08:53):

construct?

Mario Carneiro (Oct 14 2021 at 08:53):

it's a constructor, an introduction rule

Mario Carneiro (Oct 14 2021 at 08:53):

lambda is the introduction rule for pi, which is why intro is called that

Mario Carneiro (Oct 14 2021 at 08:54):

but it could easily(ish) be generalized to intro'ing arbitrary inductives too

Mario Carneiro (Oct 14 2021 at 08:55):

admittedly, everything gets turned around when working on the goal, so introduction patterns make type operators go away

Gabriel Ebner (Oct 14 2021 at 08:56):

Mario Carneiro said:

alternatively, we could just lean into constructor if the name isn't taken

Is there any difference between constructor and split besides split having a shorter name?

Mario Carneiro (Oct 14 2021 at 08:57):

constructor applies any of the constructors, not just the first

Mario Carneiro (Oct 14 2021 at 08:58):

but I don't find this difference in behavior particularly helpful since it's basically just rejecting some class of inputs that could be reasonably handled

Mario Carneiro (Oct 14 2021 at 08:59):

that is, if you made split an alias to constructor today mathlib would still build

Johan Commelin (Oct 14 2021 at 08:59):

Can we merge split and split_ifs? It's hard to beat split if it comes to meaningful tactic names: take the goal and split it into subgoals for me.

Mario Carneiro (Oct 14 2021 at 08:59):

split and split_ifs are completely different

Johan Commelin (Oct 14 2021 at 08:59):

Under the hood.

Mario Carneiro (Oct 14 2021 at 09:00):

no, they visibly have very different effects

Mario Carneiro (Oct 14 2021 at 09:00):

if you have (if a then b else c) /\ d then split turns the goal into if a then b else c and d and split_ifs turns the goal into b /\ d and c /\ d

Gabriel Ebner (Oct 14 2021 at 09:01):

Okay, I'm gonna remove split for now in favor of constructor: https://github.com/leanprover-community/mathlib4/pull/70
We can always set up a shorter alias if we find a better name.

Johan Commelin (Oct 14 2021 at 09:02):

@Mario Carneiro super_split could give me three goals: b, c, and d.

Mario Carneiro (Oct 14 2021 at 09:02):

no takers for mk? The golfers will love us

Johan Commelin (Oct 14 2021 at 09:03):

What I like about split is that it's a verb. constructor isn't.

Johan Commelin (Oct 14 2021 at 09:03):

mk is a vrb, I guess. mk s vrb, gss.

Mario Carneiro (Oct 14 2021 at 09:03):

constr, you get to decide whether it's abbreviating a noun or verb

Mario Carneiro (Oct 14 2021 at 09:04):

∧I

Mario Carneiro (Oct 14 2021 at 09:06):

If mk takes an optional (space-separated?) list of arguments, like use, I think it will be pretty convenient

Johan Commelin (Oct 14 2021 at 09:07):

It would replace rfn (aka refine), right?

Mario Carneiro (Oct 14 2021 at 09:07):

right

Mario Carneiro (Oct 14 2021 at 09:08):

I almost never use split normally

Johan Commelin (Oct 14 2021 at 09:08):

But it's very beginner-friendly. Which is why I'm sad to see it go.

Mario Carneiro (Oct 14 2021 at 09:09):

and_intro seems pretty friendly

Johan Commelin (Oct 14 2021 at 09:09):

You mean split_and?

Mario Carneiro (Oct 14 2021 at 09:10):

we could do that

Johan Commelin (Oct 14 2021 at 09:10):

But I think that you main point is that it would be nice to have a very cheap way to switch to term mode. exact is quite long for that.

Mario Carneiro (Oct 14 2021 at 09:11):

having be an exact-shortcut would be nice

Gabriel Ebner (Oct 14 2021 at 09:11):

We could make ⟨?left, ?right⟩ a tactic, this should be unambiguous.

Johan Commelin (Oct 14 2021 at 09:11):

by puts you in tactic mode. How do you leave it? With as little chars as possible?

Mario Carneiro (Oct 14 2021 at 09:11):

did you know that lean 3 has exact-shortcuts too? There is only one though, and it is hard coded: calc

Johan Commelin (Oct 14 2021 at 09:11):

would work whenever there is a constructor that you want to use, right? But it's not the general thing.

Mario Carneiro (Oct 14 2021 at 09:12):

calc is not a tactic, but you don't need to write exact first by magic

Johan Commelin (Oct 14 2021 at 09:12):

calc even uses refine these dats (-;

Mario Carneiro (Oct 14 2021 at 09:13):

We can make most expr-starters be exact-shortcuts, except for identifiers, which are unfortunately quite common

Mario Carneiro (Oct 14 2021 at 09:14):

I don't think we should interpret an unknown tactic identifier as an exact-shortcut because that will cause forward compatibility problems

Johan Commelin (Oct 14 2021 at 09:14):

from is of course also a way to switch to term mode, in lean 3. But it's still 4 chars.

Johan Commelin (Oct 14 2021 at 09:14):

Would t or x be too cryptic?

Mario Carneiro (Oct 14 2021 at 09:14):

=

Gabriel Ebner (Oct 14 2021 at 09:14):

macro (priority := 0) t:term : tactic => `(tactic| exact $t)
example : True := by True.intro

Johan Commelin (Oct 14 2021 at 09:14):

That's the best solution, I guess.

Gabriel Ebner (Oct 14 2021 at 09:15):

I'm not sure if this too cryptic though.

Mario Carneiro (Oct 14 2021 at 09:15):

Like I said, I don't think that's a good idea because tactic names will now compete with variable and constant names. Think about ring for example

Gabriel Ebner (Oct 14 2021 at 09:15):

It's Ring, now.

Mario Carneiro (Oct 14 2021 at 09:16):

checkmate

Johan Commelin (Oct 14 2021 at 09:16):

But it's Ring in both cases, right?

Mario Carneiro (Oct 14 2021 at 09:16):

no, tactics are snake case

Johan Commelin (Oct 14 2021 at 09:16):

check_Mate

Mario Carneiro (Oct 14 2021 at 09:17):

It's also going to interact weirdly with tactic combinators

Gabriel Ebner (Oct 14 2021 at 09:18):

Is it any worse than exact, though?

Mario Carneiro (Oct 14 2021 at 09:19):

Not sure. I wouldn't be surprised if some parsing oddity shows up like with the - block syntax

Mario Carneiro (Oct 14 2021 at 09:20):

that said, I'm not really too much against the pattern. MM0 has had refine-shortcut exactly like this since the beginning

Gabriel Ebner (Oct 14 2021 at 09:22):

There is one unfortunate ambiguity though: by rfl

Mario Carneiro (Oct 14 2021 at 09:24):

luckily rfl means exact rfl in lean 4 so there is no problem

Gabriel Ebner (Oct 14 2021 at 09:24):

Don't forget about the nondeterministic tactics. :smile: It could also mean exact Iff.rfl.

Gabriel Ebner (Oct 14 2021 at 09:27):

It also breaks rw [l] at h. :shrug: https://github.com/leanprover-community/mathlib4/pull/71

Mario Carneiro (Oct 14 2021 at 09:28):

Did you set the priority right? Tactics should always win

Gabriel Ebner (Oct 14 2021 at 09:29):

I hope so. At least I tried priority := 0 and priority := low and it didn't make a difference.

Mario Carneiro (Oct 14 2021 at 09:31):

The set of leading tactic tokens is known to the system, right? Can we make a custom parser for "term, but where the first token is not a tactic token"

Mario Carneiro (Oct 14 2021 at 09:32):

that should also prevent parser issues where a syntactically incorrect tactic backtracks a lot and gets parsed as a term

Gabriel Ebner (Oct 14 2021 at 09:32):

If I remove the have above, then it works..

Mario Carneiro (Oct 14 2021 at 09:33):

what does the bad code look like?

Gabriel Ebner (Oct 14 2021 at 09:33):

lemma implies_of_if_pos {c t e : Prop} [Decidable c] (h : ite c t e) : c  t :=
by intro hc
   have hp : ite c t e = t := if_pos hc
   rwa [hp] at h

Mario Carneiro (Oct 14 2021 at 09:34):

I think it's treating have as a term

Gabriel Ebner (Oct 14 2021 at 09:34):

I agree, but I don't know why.

Mario Carneiro (Oct 14 2021 at 09:34):

it's a longer match?

Mario Carneiro (Oct 14 2021 at 09:36):

woe is us for making the tactic language look so much like the term language...

Mac (Oct 15 2021 at 13:27):

Mario Carneiro said:

that should also prevent parser issues where a syntactically incorrect tactic backtracks a lot and gets parsed as a term

:up: I tried a similar strategy in Papyrus. This will cause virtually all tactic syntax errors to turn into very hard to debug term errors. You need some kind of token to enter term mode. I plan on using # in papyrus, and I think it could be a good idea here as well.

Mario Carneiro (Oct 15 2021 at 13:28):

we already have such a token, it is exact

Mac (Oct 15 2021 at 13:29):

@Mario Carneiro yes but that, as mentioned, is quite long

Johan Commelin (Oct 15 2021 at 13:37):

I think I like the # suggestion. Writing ##ℕ for exact cardinal.mk ℕ will look a bit funny, but besides that, I think it's an excellent symbol for the job.

Mario Carneiro (Oct 15 2021 at 13:41):

I would put a space after it

Mario Carneiro (Oct 15 2021 at 13:42):

like # #ℕ

Scott Morrison (Oct 15 2021 at 20:24):

Is % a possibility? We are use foo and foo% as a naming scheme for analogous tactics and term-elaborators, so % is going to have a "this is a term" connotation already.

Scott Morrison (Nov 29 2021 at 01:41):

Shall we backport the decision to use constructor instead of split to mathlib3? If not, we'll need some special casing in mathport to handle the translation, which seems more trouble than it is worth.

Alex J. Best (Nov 29 2021 at 03:02):

Can you say a bit more about what special casing is needed? From reading this thread it just sounds like the name split in lean4 is taken by a different tactic, so split should be renamed to something else in Lean 4, but my understanding of the whole mathport process is that there is an automated source to source translation which handles a lot harder things than just simple renames already, is the goal to have no tactic renames in the process?

Scott Morrison (Nov 29 2021 at 04:07):

I was confused, special casing is trivial: I can (and will shortly) just change https://github.com/leanprover-community/mathport/blob/master/Mathport/Syntax/Translate/Tactic/Lean3.lean#L268 to say

@[trTactic split] def trSplit : TacM Syntax := `(tactic| constructor)

which should do it.

Scott Morrison (Nov 29 2021 at 04:12):

https://github.com/leanprover-community/mathport/pull/59


Last updated: Dec 20 2023 at 11:08 UTC