Zulip Chat Archive
Stream: general
Topic: alternate tactics
Patrick Massot (May 22 2020 at 16:21):
What is the nice way to alternate two tactics until the goal is closed or neither make any progress? I know I can do repeat (tac1 <|> tac2)
but this is stupid, right?
Jalex Stark (May 22 2020 at 16:22):
why is it stupid? i thought the behavior is exactly as you described (so there probably isn't a more efficient implementation), and it's hard to imagine a shorter incantation
Jalex Stark (May 22 2020 at 16:23):
(also i usually write repeat { tac1 <|> tac2}
instead, is there any difference?)
Jalex Stark (May 22 2020 at 16:24):
what would you like to type instead, and would the behavior be different from the repeat block?
Patrick Massot (May 22 2020 at 16:24):
I should have said that tac1 and tac2 cannot succeed twice in a row.
Jalex Stark (May 22 2020 at 16:24):
oh i see, the repeat block will incur possibly a factor of 2 penalty?
Patrick Massot (May 22 2020 at 16:24):
Say tac1 succeeds. Then you repeat and first try tac1 that you know will fail before trying tac2. etc.
Patrick Massot (May 22 2020 at 16:24):
Yes
Patrick Massot (May 22 2020 at 16:25):
I need a computer scientist. Is there a computer scientist in this plane?
Jalex Stark (May 22 2020 at 16:25):
i wonder if passing your tactics to tidy works?
Kevin Buzzard (May 22 2020 at 16:27):
The penalty factor might shoot up a lot more then :-)
Alex J. Best (May 22 2020 at 16:29):
I'm not sure I understand what you want but is repeat { tac1 , tac2} <|> repeat { tac2, tac1}
better?
Jalex Stark (May 22 2020 at 16:30):
Right, I really meant "does tidy specifically know how to not re-apply a tactic it know will fail", and then if the answer is yes, looking at the tidy source will tell you the answer
but probably the answer is no, tidy
doesn't have a way to know that a tactic won't succeed twice
Jalex Stark (May 22 2020 at 16:31):
Alex J. Best said:
I'm not sure I understand what you want but is
repeat { tac1 , tac2} <|> repeat { tac2, tac1}
better?
I think yes? I think this never applies tac1
twice in a row and applies tac2
twice in a row at most once
Patrick Massot (May 22 2020 at 16:32):
This will fail if tac1 closes the goal immediately for instance
Jalex Stark (May 22 2020 at 16:32):
then use a semicolon?
Jalex Stark (May 22 2020 at 16:33):
repeat { tac1; tac2 } <|> repeat { tac2; tac1 }
Patrick Massot (May 22 2020 at 16:33):
That one may work...
Patrick Massot (May 22 2020 at 16:36):
It works on 12 examples, and we're in meta-land so I guess it counts as a proof.
Jalex Stark (May 22 2020 at 16:37):
did you have examples when you opened the question? it's possible that posting them may have led to us getting the answer faster
Jalex Stark (May 22 2020 at 16:38):
oh, does "work" mean "close the goal" or "close the goal faster than repeat { tac1 <|> tac2 }
"?
Patrick Massot (May 22 2020 at 16:39):
Close the goal without applying the same tactic twice in a row.
Patrick Massot (May 22 2020 at 16:40):
In my case it seems we can even assume we always start with tac1
Patrick Massot (May 22 2020 at 16:41):
so repeat (tac1 ; tac 2)
is good enough
Jannis Limperg (May 22 2020 at 16:43):
Here's a direct implementation (untested, ymmv):
namespace tactic
meta def iterate_alternating_aux : tactic unit → tactic unit → bool → tactic unit
:= λ t₁ t₂ stop_on_fail, do
progress ← try_core t₁,
match progress, stop_on_fail with
| some _, _ := iterate_alternating_aux t₂ t₁ ff
| none, ff := iterate_alternating_aux t₂ t₁ tt
| none, tt := pure ()
end
meta def iterate_alternating (t₁ t₂ : tactic unit) : tactic unit :=
iterate_alternating_aux t₁ t₂ ff
end tactic
namespace tactic.interactive
meta def iterate_alternating (t₁ t₂ : itactic) : tactic unit :=
tactic.iterate_alternating t₁ t₂
end tactic.interactive
Patrick Massot (May 22 2020 at 16:54):
Thanks. Is there any advantage over the naive method that Jalex found?
Jannis Limperg (May 22 2020 at 17:04):
Jalex's tactic looks fishy to me because repeat t
never fails, so the <|> ...
should never be executed.
repeat (tac1; tac2)
behaves slightly differently than my tactic: afaiu, it stops when either tac1
or tac2
fails for the first time, whereas my tactic only stops when both tac1
and tac2
fail. So my tactic permits the sequence tac2, tac2, ...
whereas yours requires tac1, tac2, tac1, ...
.
Patrick Massot (May 22 2020 at 17:05):
Avoiding tac2, tac2 was exactly my request
Jannis Limperg (May 22 2020 at 17:07):
Then the repeat
thing should have the right semantics.
Last updated: Dec 20 2023 at 11:08 UTC