Zulip Chat Archive
Stream: general
Topic: duplicate goals
Johan Commelin (Feb 15 2019 at 11:52):
Is there a tactic that merges identical subgoals?
Johan Commelin (Feb 15 2019 at 11:53):
I'm doing a blah; blah; rw foobar; blah
and because the rw
acts on multiple goals it creates a whole bunch of subgoals that are identical.
Mario Carneiro (Feb 15 2019 at 11:59):
no, but that sounds like a good exercise
Johan Commelin (Feb 15 2019 at 11:59):
For me?
Mario Carneiro (Feb 15 2019 at 12:03):
it's not much harder than assumption
, you just unify all the goals together that have matching types
Johan Commelin (Feb 15 2019 at 12:05):
I'll see what I can do (-;
Johan Commelin (Feb 15 2019 at 14:33):
This is what I have so far
namespace tactic #print assumption -- Copied from all_goals_core private meta def merge_goals_core : list expr → list expr → tactic unit | [] ac := set_goals ac | (g :: gs) ac := mcond _ (merge_goals_core gs ac) $ do t ← infer_type g, _ new_gs ← _, all_goals_core gs (ac ++ new_gs) meta def merge_goals : tactic unit := do gs ← get_goals, merge_goals_core gs [] namespace interactive meta def merge_goals : tactic unit := tactic.merge_goals end interactive end tactic
Johan Commelin (Feb 15 2019 at 14:33):
Can any of the tactic-writing experts give me a hint on how to continue?
Johan Commelin (Feb 15 2019 at 14:34):
Aah, wait, the mcond
is coming to early.
Johan Commelin (Feb 15 2019 at 14:35):
I should first infer the type of g
Johan Commelin (Feb 15 2019 at 14:35):
And then I want to check if there is a g_old ∈ gs
that also has type t ← infer_type g
Johan Commelin (Feb 15 2019 at 14:36):
If so, I want to say that a proof of g_old
is also a proof of g
.
Johan Commelin (Feb 15 2019 at 14:36):
How do I do that?
Kenny Lau (Feb 15 2019 at 14:38):
might tactic.unify
help?
Johan Commelin (Feb 15 2019 at 14:39):
Ah, interesting, let me try...
Johan Commelin (Feb 15 2019 at 15:04):
namespace tactic private meta def map_unify (g : expr) : list expr → tactic unit | [] := fail () | (x :: xs) := unify g x <|> map_unify xs private meta def merge_goals_core : list expr → list expr → tactic unit | [] ac := set_goals ac | (g :: gs) ac := (map_unify g ac >> merge_goals_core gs ac) <|> merge_goals_core gs (ac ++ [g]) meta def merge_goals : tactic unit := do gs ← get_goals, merge_goals_core gs [] namespace interactive meta def merge_goals : tactic unit := tactic.merge_goals end interactive example : ((true ∧ true) ∧ (true ∧ true)) ∧ (((∀ (x y : ℕ), x + y = y + x) ∧ true) ∧ (true ∧ true)) := begin split; split; split, merge_goals, exact trivial, exact nat.add_comm, end end tactic
Johan Commelin (Feb 15 2019 at 15:04):
I guess map_unify
can be inlined. But I don't know which runes to use (-;
Alex J. Best (Apr 17 2020 at 00:51):
Is the tactic in this thread (from a year ago) still interesting to people? It seems useful to me, and no version of this made it to mathlib right?
Bryan Gin-ge Chen (Apr 17 2020 at 00:52):
Looks worthy of a PR to me.
Scott Morrison (Apr 17 2020 at 00:55):
What's the intended behaviour here? If I have two nat
goals, is this meant to insist they are the same?
Scott Morrison (Apr 17 2020 at 00:56):
If I have three goals, a nat, a Type, and a term of that type, will it insist that the Type is nat, and we give the same answer for both term goals??
Alex J. Best (Apr 17 2020 at 00:58):
I would say it should be conservative, probably that means only working on subsingletons (or just Props).
Last updated: Dec 20 2023 at 11:08 UTC