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