Zulip Chat Archive

Stream: general

Topic: goals accomplished, but tactic failed


Stuart Presnell (Jan 29 2022 at 17:04):

In the following #mwe, when I put the cursor at the end of the simp line I get goals accomplished in the Info View window, but I also get a red underline on end with the error tactic failed, result contains meta-variables. How is this proof both succeeding and failing?

import data.nat.factorization

open_locale big_operators

example (n : ) : ( (p : ) in n.factors.to_finset, p)  n :=
begin
  rcases (decidable.eq_or_ne n 0) with rfl | hn0, { simp },
  convert multiset.to_finset_prod_dvd_prod,
  simp [nat.prod_factors hn0.bot_lt],
end

Eric Rodriguez (Jan 29 2022 at 17:16):

Does this happen if yoh turn it into a lemma?

Stuart Presnell (Jan 29 2022 at 17:16):

Yes it does

Alex J. Best (Jan 29 2022 at 17:29):

Tactics can modify the tactic state arbitrarily and so if they have bugs situations like this can occur. The kernel always has the final day on whether a proof is ok or not, so what you are seeing is a tactic thinking it took care of everything but the kernel saying some part of the proof is still missing. You can use the tactic recover to make goals for the metavariables. But if indeed this is a tactic bug it's probably worth minimizing and reporting

Stuart Presnell (Jan 29 2022 at 17:46):

Thanks. Appending recover reveals that what's missing is decidable_eq ℕ, which I guess was a goal generated by convert multiset.to_finset_prod_dvd_prod?

Stuart Presnell (Jan 29 2022 at 18:01):

On the way to minimising this, the following produces the same error, while changing convert to exact closes the goal with no problem.

import data.nat.factorization

open_locale big_operators

lemma test (L : list ) : L.to_finset.prod id  (L : multiset ).prod :=
begin
  convert multiset.to_finset_prod_dvd_prod,
end

Stuart Presnell (Jan 29 2022 at 18:04):

Just to note that multiset.to_finset_prod_dvd_prod is something I added in #11693 that was merged yesterday. Is there any way this could be a problem that I've introduced, or is it purely a bug in convert that I've just turned up by chance?

Eric Rodriguez (Jan 29 2022 at 18:04):

no, definitely a bug in convert

Eric Rodriguez (Jan 29 2022 at 18:04):

or maybe in tactic.congr', actually

Eric Rodriguez (Jan 29 2022 at 18:05):

I think the middle line is the only thing that could go wrong:

  gs  get_goals,
  set_goals [v],
  try (tactic.congr' n),
  gs'  get_goals,
  set_goals $ gs' ++ gs

(lines 189-193 of congr.lean)

Eric Rodriguez (Jan 29 2022 at 18:05):

I'm going to try figure this out

Eric Rodriguez (Jan 29 2022 at 18:41):

also today I learned that convert supports to say that you want the equalities the other way round

Eric Rodriguez (Jan 29 2022 at 18:58):

if you want a solution, convert ... using 0 should fix it

Eric Rodriguez (Jan 29 2022 at 18:58):

I'm really not sure why but there you are

Yaël Dillies (Jan 29 2022 at 18:59):

I usually just fiddle the tactics until it works.

Eric Rodriguez (Jan 29 2022 at 19:13):

metaprogramming thread about this: https://leanprover.zulipchat.com/#narrow/stream/239415-metaprogramming-.2F.20tactics/topic/.60convert.60.3A.20why.20does.20it.20use.20.60reflexivity.20transparency.2Enone.60.3F

Stuart Presnell (Jan 29 2022 at 20:15):

Huh, I didn't know about convert ... using ..., which isn't in the documentation for convert. What exactly does it do?

Ruben Van de Velde (Jan 29 2022 at 20:19):

"Don't go so deep"

Eric Rodriguez (Jan 29 2022 at 20:19):

convert seems to me (by a rough reading) to basically basically be "make the prop target = goal and try use congr to prove it". using controls the deepness of that congr

Kyle Miller (Jan 29 2022 at 20:23):

Stuart Presnell said:

convert ... using ..., which isn't in the documentation for convert

It's hidden in the last two sentences of tactic#convert

Kyle Miller (Jan 29 2022 at 20:23):

It would be nice if the tactic documentation would have the full syntax of each tactic -- this could be automatically generated from the type of an interactive tactic, right?

Stuart Presnell (Jan 29 2022 at 20:31):

Oh, so it is!

Mario Carneiro (Jan 29 2022 at 20:39):

import tactic.basic

open tactic
#eval do
  let name := `convert,
  (args, _)  infer_type (expr.const (`tactic.interactive ++ name) []) >>= open_pis,
  fs  args.mmap (λ arg, infer_type arg >>= interactive.param_desc),
  trace $ format.join (to_fmt name :: fs.map (λ f, " " ++ f))
-- convert ← expr (using n)?

Mario Carneiro (Jan 29 2022 at 20:40):

that is roughly what the C++ code is doing to show you the tactic description in the hover

Stuart Presnell (Feb 08 2022 at 20:25):

Eric Rodriguez said:

I'm going to try figure this out

Were you able to make any progress on tracking down this bug?

(Meanwhile I've found an alternative proof that doesn't use convert, but I'm still curious about what was going on here.)

Eric Rodriguez (Feb 08 2022 at 20:30):

It's to do with the reflexivity check in convert, but I'm still not too sure why...


Last updated: Dec 20 2023 at 11:08 UTC