Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Call tactic by name
Scott Morrison (Oct 05 2022 at 04:50):
Suppose I want to write a tactic foo
that calls an interactive tactic bar
. One simple way to do this is
import tactic.bar
meta def foo : tactic unit := `[bar]
Now suppose that I insist on not importing tactic.bar
in the file where I define foo
. I am happy to rely on the user to have also imported tactic.bar
by the time foo
is actually invoked. Thus I want foo
to run a parser on the string "bar"
at invocation time, and then run the discovered tactic.
Is there a simple way to achieve this?
I see that something along these lines happens at https://github.com/leanprover-community/mathlib/blob/master/src/tactic/hint.lean#L40, but this is doing something slightly different (resolving the "`[bar]"
to an expr
, and making a new declaration from it).
Mario Carneiro (Oct 05 2022 at 07:00):
Do you need to use the interactive parser here? (the `[ ... ]
)? It is a lot easier if you can write out the expr directly
Scott Morrison (Oct 05 2022 at 09:12):
Sorry, I should #xy. All I want to do is take a file that has a tactic that calls `[ring]
, and avoid the need to have import tactic.ring
.
Mario Carneiro (Oct 05 2022 at 20:00):
that still doesn't quite answer my question. Is it possible for you to refactor the original file so that it does not need to use the `[] notation? It is the difference between calling a function which is looked up at tactic execution time (easy) and running a parser that only exists at tactic execution time (hard)
Mario Carneiro (Oct 05 2022 at 20:08):
Here's an example for calling `[ring]
:
#eval do
let e := (expr.const `tactic.interactive.ring []).app (`(@none unit):expr),
tac ← eval_expr (tactic unit) e,
tac
If at runtime the tactic.interactive.ring
declaration exists, it will be executed, otherwise it fails with a unknown declaration 'tactic.interactive.ring'
error
Scott Morrison (Oct 05 2022 at 21:38):
Great, that does it. I wanted to hack tactic.linarith
so it doesn't need to import tactic.ring
or tactic.norm_num
(until, obviously, at runtime). This trick (and the variants which handle `[ring!]
and `[norm_num]
) is exactly what I wanted. I'm trying to sort out what exactly needs to be ported to port linarith
, and the huge imports for tactic.ring
were getting in the way.
Yaël Dillies (Oct 05 2022 at 21:41):
Oh that's interesting. I would like something similar to happen for positivity
because having it defined after the point of declaration of many lemmas whose assumptions it could fulfill measn we can't use it as out_param
there.
Yaël Dillies (Oct 05 2022 at 21:42):
This is of course a worse version fo Heather's new tactic, but quite a cheap one were the imports not getting in the way.
Mario Carneiro (Oct 05 2022 at 21:45):
I don't think we want to land something like that though, because import tactic.linarith
and then using linarith
shouldn't result in a crash
Mario Carneiro (Oct 05 2022 at 21:46):
What huge imports does tactic.ring
have? I would assume it only needs basic properties of ring
, i.e. algebra.ring.basic
or so
Yaël Dillies (Oct 05 2022 at 21:47):
The answer is the same, always.
Yaël Dillies (Oct 05 2022 at 21:48):
The algebraic order hierarchy gets back into the pure algebraic hierarchy in several points because of concrete structures and the way we fix defeqs with forgetful inheritance.
Yaël Dillies (Oct 05 2022 at 21:49):
In that case, you need to define rat.cast
before you can define field
.
Yaël Dillies (Oct 05 2022 at 21:50):
This is very annoying and it keeps causing me headaches.
Scott Morrison (Oct 05 2022 at 21:59):
I agree we should be very cautious about actually landing this. A weird compromise might be for import tactic.linartih
to do the import tactic.ring
and import tactic.norm_num
, while leaving the tactic/linarith/*.lean
files without those imports. This would mean that hopefully no one gets a surprising failure from linarith
, but it's still easy to pare down imports and see what is really being used.
Mario Carneiro (Oct 05 2022 at 22:09):
I'm not sure I understand the reasoning here though. linarith
does use ring
, it will fail if you try to call it without ring
available
Mario Carneiro (Oct 05 2022 at 22:10):
it would make more sense to do this for norm_num
's lemmas
Last updated: Dec 20 2023 at 11:08 UTC