Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Communicate between successive tactics
Anatole Dedecker (Jan 27 2023 at 11:19):
What is the best way to transfer data between two different tactic calls? More specifically, I want to make two tactics A
and B
such that A
creates some metavariables, and then B
retrieves those metavariables and do things with them, possibly with many tactics invocation in between. I suppose I could use tags to find them back, but that seems like a hacky solution (and I'm not actually sure it even works)
Jannis Limperg (Jan 27 2023 at 12:00):
You could maybe store the mvars as types of hidden hypotheses in the context. What's the specific use case? (Also, Lean 3 or 4?)
Anatole Dedecker (Jan 27 2023 at 12:06):
It’s for Lean 4. I am thinking about making a version of filter_upwards
that is more flexible in that you don’t have to provide all hypotheses you want to make (as in "we can assume this and this and that because these are all true in a neighborhood of x_0
") all at once, and you can instead add them incrementally, which makes it more intuitive
Anatole Dedecker (Jan 27 2023 at 12:10):
And the way I want to do that is by having metavariables for the list of assumptions made, that I can partially instantiate when the user makes a new assumption, and eventually instantiate the remaining one with true
when we no longer have assumptions to make
Kyle Miller (Jan 27 2023 at 12:13):
Maybe you could have some special kind of tactic block that keeps track of a certain list of goal metavariables? Like perhaps your filter_upwards
has syntax that allows any number of tactics to follow it (along with, possibly, one last thing for finally filling in these lingering goals)
Anatole Dedecker (Jan 27 2023 at 12:13):
Here is an example I did "by hand" in Lean3 (so it looks very messy). Each "block" in this proof should become one tactic call, and ideally I'd use metavariables instead of goals so that this is not too frightening for the user.
import order.filter.basic
open set filter function list
variables {α β : Type*} {f : filter α} {p q r : α → Prop}
lemma test (hp : ∀ᶠ x in f, p x) (hpq : ∀ᶠ x in f, p x → q x) (hqr : ∀ᶠ x in f, q x → r x) :
∀ᶠ x in f, r x :=
begin
let _U : list (set α) := _,
have _hU : ∀ s ∈ _U, s ∈ f := _,
have _key : foldr (∩) (univ : set α) _U ∈ f :=
@foldr_rec_on (set α) (set α) (λ s, s ∈ f) _U (∩) (univ : set α) univ_mem
(λ s hs t ht, inter_mem (_hU t ht) hs),
refine mem_of_superset _key (λ x _hx, _),
dsimp only [mem_set_of],
work_on_goal 3 { refine (set_of (λ x, q x → r x)) :: _ },
work_on_goal 2 { refine forall_mem_cons.mpr ⟨hqr, _⟩, },
rw [foldr_cons] at _hx,
rcases _hx with ⟨hqrx, _hx⟩,
dsimp only [mem_set_of] at hqrx,
apply hqrx,
work_on_goal 2 { refine (set_of (λ x, p x → q x)) :: _ },
work_on_goal 3 { refine forall_mem_cons.mpr ⟨hpq, _⟩, },
rw [foldr_cons] at _hx,
rcases _hx with ⟨hpqx, _hx⟩,
dsimp only [mem_set_of] at hpqx,
apply hpqx,
work_on_goal 2 { refine (set_of p) :: _ },
work_on_goal 3 { refine forall_mem_cons.mpr ⟨hp, _⟩, },
rw [foldr_cons] at _hx,
rcases _hx with ⟨hpx, _hx⟩,
dsimp only [mem_set_of] at hpx,
exact hpx,
exact nil,
exact forall_mem_nil _
end
Anatole Dedecker (Jan 27 2023 at 12:15):
Kyle Miller said:
Maybe you could have some special kind of tactic block that keeps track of a certain list of goal metavariables? Like perhaps your
filter_upwards
has syntax that allows any number of tactics to follow it (along with, possibly, one last thing for finally filling in these lingering goals)
Oh I didn't think about doing that as one syntax for everything, that could probably work
Last updated: Dec 20 2023 at 11:08 UTC