Zulip Chat Archive
Stream: mathlib4
Topic: unknown free variable
Yury G. Kudryashov (Jan 29 2023 at 23:08):
I get the following error: unknown free variable '_uniq.56988'. The proof is here:
theorem Tendsto.isCompact_insert_range_of_cofinite {f : ι → α} {a} (hf : Tendsto f cofinite (𝓝 a)) :
    IsCompact (insert a (range f)) := by
  letI : TopologicalSpace ι := ⊥; haveI : DiscreteTopology ι := ⟨rfl⟩
  rw [← cocompact_eq_cofinite] at hf
  exact Tendsto.isCompact_insert_range_of_cocompact hf continuous_of_discreteTopology
It is also here: https://github.com/leanprover-community/mathlib4/pull/1913/files#diff-168d6c7ac4acb6033bfdf68bf30e50796594b04d24beb36a8ad595e729b9a6ecR572
Yury G. Kudryashov (Jan 29 2023 at 23:09):
Any ideas what can be the reason?
Yury G. Kudryashov (Jan 29 2023 at 23:20):
I found the reason: rw [← cocompact_eq_cofinite] generates a free var (as rw in Lean 3 sometimes did) but doesn't register it as a goal.
Yury G. Kudryashov (Jan 29 2023 at 23:20):
Specifying ι solves the problem.
Kevin Buzzard (Jan 29 2023 at 23:32):
Can you minimise?
Yury G. Kudryashov (Jan 29 2023 at 23:48):
I'll try to do it tomorrow. I've got a cold, so I'm thinking much slower than usual.
Reid Barton (Jan 29 2023 at 23:49):
I've also seen the same form of error message in what looks like a totally different situation, where I didn't understand what's going on.
Reid Barton (Jan 29 2023 at 23:50):
Does recover do anything in this example? It sounds a bit different than a metavariable not getting assigned.
Yury G. Kudryashov (Jan 29 2023 at 23:50):
You can checkout this branch and have a look.
Yury G. Kudryashov (Jan 29 2023 at 23:51):
Or I can do it later.
Mario Carneiro (Jan 29 2023 at 23:52):
This error message usually indicates a missing withContext
Mario Carneiro (Jan 29 2023 at 23:53):
Why are there letI and haveI calls in this example? The lean 4 way to spell that is let,have; letI and haveI mean something else now
Yury G. Kudryashov (Jan 29 2023 at 23:57):
What do they mean now?
Yury G. Kudryashov (Jan 29 2023 at 23:57):
mathport translated letI and haveI as letI and haveI, I didn't touch these lines.
Mario Carneiro (Jan 29 2023 at 23:57):
?? it should not have
Yury G. Kudryashov (Jan 29 2023 at 23:58):
I'll double check.
Mario Carneiro (Jan 29 2023 at 23:58):
the I means "inline" - haveI x := a; b elaborates to b[x/a] while have x := a; b elaborates to (some metadata over) (fun x => b) a
Yury G. Kudryashov (Jan 30 2023 at 00:01):
Yury G. Kudryashov (Jan 30 2023 at 00:03):
I'm going to try it with have/let
Mario Carneiro (Jan 30 2023 at 00:03):
Hm, it looks like @Gabriel Ebner changed it to introduce haveI at some point. Why is that?
Eric Rodriguez (Jan 30 2023 at 00:05):
Mario Carneiro said:
the
Imeans "inline" -haveI x := a; belaborates tob[x/a]whilehave x := a; belaborates to (some metadata over)(fun x => b) a
this is really confusing to us lean3 users - I know instances don't need resetting anymore but I assumed this was just a normal porting thing and for example this could've been just declared as a synonym for ease of use
Eric Rodriguez (Jan 30 2023 at 00:05):
I think it's really important to flag the difference so even if it's not fixed at mathport end, it's fixed in mathlib4
Eric Rodriguez (Jan 30 2023 at 00:06):
(also, this can definitely be useful for introducing haves and lets in such a way to just shorten proofs, without causing any weird syntactic difficulties!)
Mario Carneiro (Jan 30 2023 at 00:06):
Note that have-the-tactic in lean 3 was actually inlining in this sense
Mario Carneiro (Jan 30 2023 at 00:06):
have-the-term was not
Mario Carneiro (Jan 30 2023 at 00:07):
in fact, that might be why it is being aligned like that in mathport
Eric Rodriguez (Jan 30 2023 at 00:07):
i did know that have-the-term did not, but I did not know that have-the-tactic did. neat.
Yury G. Kudryashov (Jan 30 2023 at 00:22):
Same with let/have.
Reid Barton (Jan 30 2023 at 07:33):
I'm confused--there's no way that if you wrote have h := blah blah in Lean 3 and then used h multiple times in the rest of the tactic block, that h was getting duplicated into each use site, right?
Reid Barton (Jan 30 2023 at 07:33):
What's the difference between Lean 4 haveI and letI then?
Mario Carneiro (Jan 30 2023 at 07:36):
def foo : nat := begin
  have := 1,
  have := this + this,
  have := this + this,
  have := this + this,
  exact this,
end
#print foo
-- def foo : ℕ :=
-- 1 + 1 + (1 + 1) + (1 + 1 + (1 + 1))
Mario Carneiro (Jan 30 2023 at 07:36):
Note that this isn't as expensive as you might think since the term is deduplicated
Reid Barton (Jan 30 2023 at 07:36):
Is this why mathlib is slow?
Mario Carneiro (Jan 30 2023 at 07:38):
Reid Barton said:
What's the difference between Lean 4
haveIandletIthen?
Same as the difference between have and let, except the effects are all felt before getting to the kernel term
Mario Carneiro (Jan 30 2023 at 07:38):
letI inserts a x : t := e into the local context so simp and friends can unfold it
Gabriel Ebner (Jan 30 2023 at 22:23):
Mario Carneiro said:
Hm, it looks like Gabriel Ebner changed it to introduce
haveIat some point. Why is that?
You correctly guessed it.  The have ...; exact ... idiom was mainly used in Lean 3 to declare local instances.  Those should not produce a have-term in the elaborated expression and are therefore translated to haveI.
Last updated: May 02 2025 at 03:31 UTC