Zulip Chat Archive
Stream: general
Topic: Tactic timeout
Rémy Degenne (Jun 16 2022 at 12:14):
I have observed a weird timeout in the measurability tactic and I would like to debug it but I don't know anything about how to do that. Here is the mwe:
import measure_theory.tactic
import measure_theory.constructions.prod
example : measurable (λ p : ℝ × ℝ, p.fst + p.snd) :=
by measurability -- fast
example {ι : Type*} (i k : ι) (hik : i ≠ k) : measurable (λ p : ℝ × ℝ, p.fst + p.snd) :=
by measurability -- deterministic timeout
in the second example I added some variables which are completely irrelevant, and I get a timeout. Removing hik
makes it fast. I am interested in understanding why that happens, but I would be even more thankful if somebody could give me indications on how to debug that tactic myself.
Rémy Degenne (Jun 16 2022 at 12:41):
Replacing i ≠ k
by i = k
also makes it fast.
Rob Lewis (Jun 16 2022 at 15:40):
First the explanation, then how I got there: the measurability
tactic tries to call a bunch of different rules. One of them is apply_assumption
, which will cause a loop if there's any negated hypothesis. First apply_any
tries to apply each hypothesis directly. Then it calls symmetry
and goes again. Then it calls exfalso
and goes again. But if you have h : ¬ P
in your context, this will always apply after calling exfalso
. So measurability
(via tidy
) ends up in an infinite loop of exfalso, apply hik
.
Rob Lewis (Jun 16 2022 at 15:43):
To figure this out I looked at the definition of measurability
and saw that it's essentially tactic.tidy { tactics := measurability_tactics }
. I pasted this into your example and still saw the same behavior. Then I copied measurability_tactics
and commented out the first one, and the behavior changed; I commented everything but the first one and the behavior returned, so that meant it was likely something with the apply_assumption
rule.
Rémy Degenne (Jun 16 2022 at 15:54):
Thanks for the explanation!
That call to apply_assumption
is something I added when I adapted the continuity
tactic to prove measurability. It has been there for a while and now I am surprised that we did not stumble upon that problem earlier.
Rémy Degenne (Jun 16 2022 at 15:58):
The only assumptions I really want to apply are of the shape measurable
or measurable_set
etc. I guess the safe way to replace apply_assumption
is to write a tactic that applies only the ones I want.
Rob Lewis (Jun 16 2022 at 16:08):
You could also modify apply_assumption
to take an optional apply_any_opt
config argument, which you can use to disable the exfalso
behavior
Rémy Degenne (Jun 16 2022 at 16:10):
Thanks! That's what I also realized and I am doing that right now! I need to figure out the syntax for passing config options first :)
Rob Lewis (Jun 16 2022 at 16:15):
You should be able to do something like
meta def apply_assumption (opt : apply_any_opt := {}) : tactic unit :=
local_context >>= apply_any opt
meta def measurability_tactics' (md : transparency := semireducible) : list (tactic string) :=
[
propositional_goal >> apply_assumption {use_exfalso := ff}
>> pure "apply_assumption"
...]
Rémy Degenne (Jun 16 2022 at 16:24):
I could almost write exactly that. The apply_assumption tactic you wrote returns an error, but can be written as
meta def apply_assumption' (opt : apply_any_opt := {}) : tactic unit :=
do l ← local_context, apply_any l opt
It looks like it all works now. Thanks again!
Last updated: Dec 20 2023 at 11:08 UTC