Zulip Chat Archive
Stream: general
Topic: rw: equality is not an equality
Kevin Buzzard (May 06 2020 at 20:25):
I've never seen anything like this before. rw h2
on line 26 fails because it claims h2
is not an equality. But it is, and rw h2.symm.symm
works fine. What's going on?
def fibZ : ℕ → ℤ
| 0 := 0
| 1 := 1
| (n + 2) := fibZ n + fibZ (n + 1)
@[simp] lemma fibZ_0 : fibZ 0 = 0 := rfl
@[simp] lemma fibZ_1 : fibZ 1 = 1 := rfl
@[simp] lemma fibZ_succ_succ (n : ℕ) : fibZ (n + 2) = fibZ n + fibZ (n + 1) := rfl
lemma induction2 (P : ℕ → Prop) (h0 : P 0) (h1 : P 1)
(hind : ∀ d : ℕ, P d → P(d+1) → P(d+2)) : ∀ n, P n := sorry
lemma fibZ_m_n (m n : ℕ) : fibZ(m+n+1)=fibZ(m+1)*fibZ(n+1)+fibZ(m)*fibZ(n) :=
begin
apply induction2 _ _ _ _ n,
{ simp},
{ show fibZ (m + 2) = fibZ (m + 1) * 1 + fibZ m * 1 ,
rw fibZ_succ_succ,
simp [add_comm]},
{ -- inductive step
intros d h1 h2,
show fibZ (m + (d + 1) + 2) = fibZ (m + 1) * fibZ ((d + 1) + 2) + fibZ m * fibZ (d + 2),
rw fibZ_succ_succ d,
rw fibZ_succ_succ (d+1),
rw fibZ_succ_succ (m+(d+1)),
-- rw h2, -- "lemma is not an equality or iff" <---- is this a bug?
rw h2.symm.symm, -- works fine
rw [←add_assoc m],
rw h1.symm.symm,
simp [mul_add, mul_comm, add_comm, add_assoc, mul_assoc],
ac_refl,
}
end
Mario Carneiro (May 06 2020 at 20:26):
it's probably an instantiated metavariable
Kevin Buzzard (May 06 2020 at 20:26):
you mean a variable?
Mario Carneiro (May 06 2020 at 20:26):
no
Kevin Buzzard (May 06 2020 at 20:26):
oh
Mario Carneiro (May 06 2020 at 20:26):
It has type h2 : ?m
where ?m := a = b
or somesuch
Kevin Buzzard (May 06 2020 at 20:27):
how do I test for this?
Mario Carneiro (May 06 2020 at 20:27):
this is pretty printed as h2 : a = b
but rw
is fussy about it in this particular case
Kevin Buzzard (May 06 2020 at 20:27):
but pp.all doesn't show it me, right?
Kevin Buzzard (May 06 2020 at 20:28):
simp at h2
before the rewrite fixes it
Kevin Buzzard (May 06 2020 at 20:28):
So did I write bad code to get this situation?
Kevin Buzzard (May 06 2020 at 20:29):
my code looks really innocuous and fine
Kevin Buzzard (May 06 2020 at 20:31):
if I change apply induction2 _ _ _ _ n
to refine induction2 _ _ _ _ n
the problem goes away
Chris Hughes (May 06 2020 at 20:32):
What is an instantiated metavariable?
Mario Carneiro (May 06 2020 at 20:33):
lemma fibZ_m_n (m n : ℕ) : fibZ(m+n+1)=fibZ(m+1)*fibZ(n+1)+fibZ(m)*fibZ(n) :=
begin
apply induction2 _ _ _ _ n,
{ simp},
{ show fibZ (m + 2) = fibZ (m + 1) * 1 + fibZ m * 1 ,
rw fibZ_succ_succ,
simp [add_comm]},
{ -- inductive step
intros d h1 h2,
show fibZ (m + (d + 1) + 2) = fibZ (m + 1) * fibZ ((d + 1) + 2) + fibZ m * fibZ (d + 2),
rw fibZ_succ_succ d,
rw fibZ_succ_succ (d+1),
rw fibZ_succ_succ (m+(d+1)),
(do t ← tactic.to_expr```(h2) >>= tactic.infer_type,
-- t ← tactic.instantiate_mvars t, -- uncomment this line
tactic.trace (expr.to_raw_fmt t)
-- (app (mvar _mlocal._fresh.378.4796 _mlocal._fresh.378.4796 (const 2 []))
-- (app (app (app (app (const has_add.add [0]) (const nat [])) (const nat.has_add []))
-- (local_const 0._fresh.378.6836 d (const 1 []))) (app (app (const has_one.one [0])
-- (const nat [])) (const nat.has_one []))))
),
-- rw h2, -- "lemma is not an equality or iff" <---- is this a bug?
rw h2.symm.symm, -- works fine
rw [←add_assoc m],
rw h1.symm.symm,
simp [mul_add, mul_comm, add_comm, add_assoc, mul_assoc],
ac_refl,
}
end
Mario Carneiro (May 06 2020 at 20:34):
expr.to_raw_fmt
is like the super verbose version of pp.all
Mario Carneiro (May 06 2020 at 20:34):
it shows you exactly what constructors of the expr
type are being used
Mario Carneiro (May 06 2020 at 20:35):
As you can see, it starts (app (mvar ...
Kenny Lau (May 06 2020 at 20:35):
then where is the information stored that ?m_2
is eq
?
Mario Carneiro (May 06 2020 at 20:35):
in the local context, not somewhere easily accessible to lean except through builtins like instantiate_mvars
Kenny Lau (May 06 2020 at 20:36):
can we tell intro
to instantiate metavariables?
Mario Carneiro (May 06 2020 at 20:37):
I haven't looked at what is causing the problem in the first place in this case
Mario Carneiro (May 06 2020 at 20:39):
The only metavariable that intro
instantiates is the goal. It doesn't have to solve any unification problems
Mario Carneiro (May 06 2020 at 20:42):
It might make things clearer to replace the first line with:
have := induction2 _ _ _ _ n, apply this,
After the have, the state is
5 goals
m n : ℕ,
this : ?m_1 n
⊢ fibZ (m + n + 1) = fibZ (m + 1) * fibZ (n + 1) + fibZ m * fibZ n
m n : ℕ
⊢ ℕ → Prop
m n : ℕ
⊢ ?m_1 0
m n : ℕ
⊢ ?m_1 1
m n : ℕ
⊢ ∀ (d : ℕ), ?m_1 d → ?m_1 (d + 1) → ?m_1 (d + 2)
The thing that will eventually become the type of h2
is here ?m_1 (d + 1)
Kevin Buzzard (May 06 2020 at 20:43):
The problem is somehow with the apply
on the first line.
Kevin Buzzard (May 06 2020 at 20:43):
yeah, that. refine
fixes it.
Mario Carneiro (May 06 2020 at 20:43):
Because refine
knows the expected type, and apply
doesn't, elaboration happens in a different order here
Mario Carneiro (May 06 2020 at 20:44):
apply
is doing the above two stage process, while refine
never creates ?m_1 (d + 1)
because it already knows what ?m_1
is
Kevin Buzzard (May 06 2020 at 20:45):
When I saw the underscores I thought about maybe making induction2_on and applying that instead; I don't know if that would have fixed the problem.
Kevin Buzzard (May 06 2020 at 20:45):
[this code is for pedagogical purposes]
Mario Carneiro (May 06 2020 at 20:46):
Notice that the variable in question is pretty far from apply
's strike zone. It's in a subterm of a different goal
Mario Carneiro (May 06 2020 at 20:47):
I'm not sure if this is a factor, but there is a performance penalty for instantiate_mvars
because it has to traverse the whole term, while most tactics try to keep track of where all the metavariables are so that they don't have to go hunting
Mario Carneiro (May 06 2020 at 20:49):
But the check in rw
is just plain broken. It's pattern matching on the expr and assumes that an mvar
is not an eq
. This is a very common pattern, but it is not safe against rogue terms with instantiated mvars
Mario Carneiro (May 06 2020 at 20:54):
Here's another example that often comes up for me:
example (n : ℕ) (h : n + n ≠ 0) : n ≠ 0 :=
begin
refine mt (λ hz, _) h,
rw hz -- rewrite tactic failed, lemma is not an equality nor a iff
end
Mario Carneiro (May 06 2020 at 20:55):
The type of hz
is an instantiated metavariable here because it is unknown when it is created by the lambda and is solved by the h
to its right
Patrick Massot (May 06 2020 at 20:55):
I think you complain periodically about that one. Couldn't you change that in Lean 3.13?
Patrick Massot (May 06 2020 at 20:55):
(I lost track of what it the next version)
Mario Carneiro (May 06 2020 at 21:00):
instantiated mvars or the rw
check?
Patrick Massot (May 06 2020 at 21:00):
The rw check
Mario Carneiro (May 06 2020 at 21:00):
I know nothing about the code in question but it shouldn't be hard
Patrick Massot (May 06 2020 at 21:01):
I think you already found the offending line at some point
Mario Carneiro (May 06 2020 at 21:08):
I'm building lean now, if I can remember how to do that
Bhavik Mehta (May 06 2020 at 21:24):
I've seen this a couple of times but only very recently
Mario Carneiro (May 06 2020 at 21:25):
Reid Barton (May 06 2020 at 22:34):
BTW, this "instantiation" is more formally known as zonking
Last updated: Dec 20 2023 at 11:08 UTC