Zulip Chat Archive
Stream: mathlib4
Topic: library_search getting tired
Patrick Massot (May 18 2023 at 14:49):
I've been using mathlib4 a bit recently ("using" being opposed to "porting") and I noticed that library_search
gets tired after a couple of invocation. When it's tired it immediately gives up instead of searching. Reloading the file (say by using "Refresh file dependency") reboots library_search
which then works normally for a while.
Patrick Massot (May 18 2023 at 14:50):
This is in projects depending on mathlib4, not mathlib4 itself, in case this matters.
Scott Morrison (May 18 2023 at 14:55):
Hmm... library_search
now does play some clever tricks to try to stop if maxHeartbeats
is approaching, and this is surely where the suspicion should lie. If you have a file where this somewhat reliably happens I could try disabling the maxHeartbeats check.
Patrick Massot (May 18 2023 at 15:21):
Of course now that I posted this message I can't get this bug to appear.
Patrick Massot (May 18 2023 at 15:24):
I still have something weird to show. In
import Mathlib.Topology.MetricSpace.Basic
import Mathlib.Topology.UniformSpace.Compact
import Mathlib.Tactic.LibrarySearch
notation "d" => dist
attribute [aesop (rule_sets [Continuous]) apply unsafe] Continuous.continuousOn
macro "ls" : tactic => `(tactic| library_search)
theorem Heine_Cantor [MetricSpace X] [MetricSpace Y] [CompactSpace X]
{f : X → Y} (hf : Continuous f) : UniformContinuous f := by
rw [Metric.uniformContinuous_iff]
intros ε ε_pos
set K := { p : X × X | ε ≤ d (f p.1) (f p.2) }
have K_closed : IsClosed K := by
apply isClosed_le
continuity
continuity
have K_cpct : IsCompact K := by exact IsClosed.isCompact K_closed
cases' K.eq_empty_or_nonempty with h h
· use 1, zero_lt_one
intros x y _
have : (x, y) ∉ K
· simp [h]
simpa using this
obtain ⟨p, p_in, H⟩ : ∃ p ∈ K, ∀ q : X × X, q ∈ K → d p.1 p.2 ≤ d q.1 q.2
· apply K_cpct.exists_forall_le h
continuity
use d p.1 p.2
constructor
· simp
intro eq
apply lt_irrefl ε
calc
ε ≤ 0 := by simpa [eq] using p_in
_ < ε := ε_pos
· intros x x'
contrapose!
aesop
replacing line 28, the one saying apply K_cpct.exists_forall_le h
by library_search
and accepting the suggestion leads to a weird error.
Patrick Massot (May 18 2023 at 15:25):
This is on current mathlib4 master c39117e4de1eff79d24b7512e26aff0f0b5ade4b
Dan Velleman (May 18 2023 at 15:26):
I have experienced this problem as well.
Patrick Massot (May 18 2023 at 15:27):
It seems that library_search takes the initiative to name the hole to be filled and this name clashes with an existing name and confuses Lean.
Patrick Massot (May 18 2023 at 15:27):
Fun fact in passing: accepting this suggestion also raises a deprecation warning which does not show up in the hand-written version because dot notation seems to turn off deprecation warnings.
Mario Carneiro (May 18 2023 at 15:29):
Patrick Massot said:
It seems that library_search takes the initiative to name the hole to be filled and this name clashes with an existing name and confuses Lean.
This is actually a bug in apply
IIRC
Kevin Buzzard (May 18 2023 at 15:36):
I was missing the apply
bug :-)
Patrick Massot (May 18 2023 at 15:37):
In this case it's also a refine
bug.
Mario Carneiro (May 18 2023 at 15:37):
What is the exact suggestion?
Patrick Massot (May 18 2023 at 15:39):
refine IsCompact.exists_forall_le K_cpct h ?hf
Patrick Massot (May 18 2023 at 15:39):
And hf
is already the name of a local assumption.
Mario Carneiro (May 18 2023 at 15:39):
That's by design, although it is a somewhat dubious design
Mario Carneiro (May 18 2023 at 15:40):
The issue is that named metavariables are not really scoped in any meaningful sense, so you can end up picking up completely unrelated mvars which happen to have the same name
Mario Carneiro (May 18 2023 at 15:41):
sometimes even mvars you never wrote but were generated internally - this is what apply
does
Mario Carneiro (May 18 2023 at 15:41):
have you identified who created the ?hf
mvar?
Mario Carneiro (May 18 2023 at 15:42):
if you write let := ?hf
you might recognize the proof term
Patrick Massot (May 18 2023 at 15:45):
This named is made up by library_search
Mario Carneiro (May 18 2023 at 15:53):
no, I mean the first ?hf
in the proof
Mario Carneiro (May 18 2023 at 15:53):
if you try writing let := ?hf
you might be surprised to see the result
Patrick Massot (May 18 2023 at 15:53):
The first hf
is an assumption from the statement of the theorem.
Mario Carneiro (May 18 2023 at 15:54):
not hf
, ?hf
Mario Carneiro (May 18 2023 at 15:54):
mvars have a separate namespace, they are unrelated to local variables with the same name
Mario Carneiro (May 18 2023 at 15:55):
although apply and other tactics have a penchant for naming mvars after the local variables they will substitute for
Patrick Massot (May 18 2023 at 15:55):
No idea. It don't see it anywhere.
Mario Carneiro (May 18 2023 at 15:55):
and what does let := ?hf
do to the tactic state?
Patrick Massot (May 18 2023 at 15:57):
I'll be back later, I need to be in Cambridge for a while.
Mario Carneiro (May 18 2023 at 15:58):
just got to a lean to test this out myself. let := ?hf
is a syntax error but let foo := ?hf
puts
foo: Continuous fun b ↦ ε := continuous_const
in the context
Mario Carneiro (May 18 2023 at 15:59):
by moving the line around it appears that this ?hf
variable appears due to the first continuity
in
have K_closed : IsClosed K := by
apply isClosed_le
continuity
continuity
Mario Carneiro (May 18 2023 at 16:01):
and indeed, you will notice that the case tag on this continuity
goal is hf
Mario Carneiro (May 18 2023 at 16:01):
created by the apply
on the previous line
Mario Carneiro (May 18 2023 at 16:07):
Oh, this is fun:
def foo (x y : Nat) : Nat := x + y
def bla : Nat := by
apply foo
exact ?x
crashes the server
Mario Carneiro (May 18 2023 at 16:21):
another brainteaser: Why does
def foo (x y : Nat) : Nat := x + y
#eval show Nat from
(let a : Nat := by
apply foo
exact 0
exact 10
by exact ?x) +
(let b : Nat := by
apply foo
exact 2
exact 30
by exact ?x)
print 4
?
Kevin Buzzard (May 18 2023 at 16:24):
Because it's 2+2, with the 2 being the exact 2
, which was the value of ?x
when it was assigned in both cases I guess (although I don't understand elaboration order at all)
Mario Carneiro (May 18 2023 at 16:25):
Yet
#eval show Nat from
(by
let a : Nat := by
apply foo
exact 0
exact 1
exact ?x) +
(let b : Nat := by
apply foo
exact 2
exact 3
by exact ?x)
is 0
, and
#eval show Nat × Nat from
(
let a : Nat := by
apply foo
exact 0
exact 1
by exact ?x
,
let b : Nat := by
apply foo
exact 2
exact 3
by exact ?x
)
is (0, 2)
Patrick Massot (May 18 2023 at 17:15):
Very interesting...
Last updated: Dec 20 2023 at 11:08 UTC