Zulip Chat Archive
Stream: general
Topic: result contains metavariables
Kevin Buzzard (Mar 18 2020 at 20:46):
I've been around for long enough to have seen the situation where you have no goals but end
doesn't work because
tactic failed, result contains meta-variables state: no goals
You can try and get out of this hole with the recover
tactic.
I've been playing with the category theory library this evening, and something pretty cool happened, and I have no idea why. We're in one of these situations where the goal should be relatively straightforward when you work out what it says. My strategy in such situations is to do a mass of unfolding, and when dsimp
suddenly tidies a bunch of stuff up, save my position with show [blah]
and then press on. So I managed to fill in a sorry this evening, and my first complete proof looked like this:
@[simp] lemma right_unitor_hom {M : Module R} (r : R) (m : M) : ((ρ_ M).hom : M ⊗ 𝟙_ (Module R) ⟶ M) (m ⊗ₜ r) = r • m := begin show (linear_equiv.to_linear_map (tensor_product.rid R ↥M)) (m ⊗ₜ[R] r) = r • m, dunfold tensor_product.rid, dunfold tensor_product.comm, unfold_coes, unfold linear_map.flip, unfold_coes, unfold linear_map.mk₂, unfold tensor_product.mk, dsimp, unfold_coes, -- unfold tensor_product.lift, unfold linear_equiv.of_linear, unfold linear_equiv.trans, dunfold linear_equiv.to_linear_map, dsimp, unfold tensor_product.lid, unfold linear_equiv.of_linear, dsimp, unfold_coes, unfold linear_map.lsmul, unfold linear_map.mk₂, dsimp, squeeze_simp, -- tensor_product.lift.tmul used here show (tensor_product.lift {to_fun := λ (a : R), {to_fun := λ (m : ↥M), a • m, add := _, smul := _}, add := _, smul := _}).to_fun (r ⊗ₜ[R] m) = r • m, squeeze_simp, -- tensor_product.lift.tmul' refl, end
This proof is actually just two lines long -- each squeeze_simp
just does one rewrite (tmul
and tmul'
are definitionally equal, one has to_fun
in and the other has a coercion), and all the definitional unfolding is just to get things into a shape where the rewrite can happen. This proof compiles no problem. So then I refactored the proof so it was just show X, rw tensor_product.lift.tmul', show Y, rw tensor_product.lift.tmul'
:
lemma right_unitor_hom {M : Module R} (r : R) (m : M) : ((ρ_ M).hom : M ⊗ 𝟙_ (Module R) ⟶ M) (m ⊗ₜ r) = r • m := begin show (tensor_product.lift {to_fun := λ (a : R), {to_fun := λ (m : ↥M), a • m, add := _, smul := _}, add := _, smul := _}).to_fun ((tensor_product.lift {to_fun := λ (m : ↥M), {to_fun := λ (m_1 : R), m_1 ⊗ₜ[R] m, add := _, smul := _}, add := _, smul := _}).to_fun (m ⊗ₜ[R] r)) = r • m, rw tensor_product.lift.tmul', show (tensor_product.lift {to_fun := λ (a : R), {to_fun := λ (m : ↥M), a • m, add := _, smul := _}, add := _, smul := _}).to_fun (r ⊗ₜ[R] m) = r • m, rw tensor_product.lift.tmul', refl, -- no goals! end
and I got the result contains metavariables
error. I was really surprised when I tried recover
though -- four goals, some of which weren't definitional. I killed them all and still I got the error! A second recover
and they were finally gone. My proof ended up looking like this:
lemma right_unitor_hom {M : Module R} (r : R) (m : M) : ((ρ_ M).hom : M ⊗ 𝟙_ (Module R) ⟶ M) (m ⊗ₜ r) = r • m := begin show (tensor_product.lift {to_fun := λ (a : R), {to_fun := λ (m : ↥M), a • m, add := _, smul := _}, add := _, smul := _}).to_fun ((tensor_product.lift {to_fun := λ (m : ↥M), {to_fun := λ (m_1 : R), m_1 ⊗ₜ[R] m, add := _, smul := _}, add := _, smul := _}).to_fun (m ⊗ₜ[R] r)) = r • m, rw tensor_product.lift.tmul', show (tensor_product.lift {to_fun := λ (a : R), {to_fun := λ (m : ↥M), a • m, add := _, smul := _}, add := _, smul := _}).to_fun (r ⊗ₜ[R] m) = r • m, rw tensor_product.lift.tmul', refl, -- no goals! recover, -- four goals! simp, intros, congr', intros, ext, simp, apply tensor_product.tmul_add, -- no goals! recover, -- two goals! intros, rw tensor_product.smul_tmul c x m_1, simp, intros, apply tensor_product.add_tmul, end
My question: How come I managed to avoid these six secret metavariables in my first proof? Where did they come from?
One cannot immediately reproduce this at home, but because of the new tooling it is much easier than before. The following commands (run in a directory where there's not a subdirectory called mathlib
):
leanproject get mathlib cd mathlib/ git checkout enriched leanproject get-cache
will give you Scott's branch, fully compiled. The right_unitor_hom
lemma is on line 149 of src/algebra/category/Module/monoidal.lean
Kevin Buzzard (Mar 18 2020 at 21:17):
Some of the random goals are I think the add := _
and smul := _
. I tried replacing the first show
with
show (tensor_product.lift {to_fun := λ (a : R), {to_fun := λ (m : ↥M), a • m, add := _, smul := _}, add := _, smul := _}).to_fun ((tensor_product.lift {to_fun := _, add := _, smul := _}).to_fun (m ⊗ₜ[R] r)) = r • m,
and I get
LEAN ASSERTION VIOLATION File: /home/travis/build/leanprover-community/lean/src/frontends/lean/elaborator.cpp Line: 3174 Task: /home/buzzard/Encfs/Computer_languages/Lean/lean-projects/mathlib/src/algebra/category/Module/monoidal.lean: Module.monoidal_category.right_unitor_hom m_ctx.match(e, *val2)
Something is a bit weird here.
Bryan Gin-ge Chen (Mar 18 2020 at 21:18):
Looks like https://github.com/leanprover-community/lean/issues/123 again.
Kevin Buzzard (Mar 18 2020 at 21:22):
no, you can do set-theoretic trickery. Wait, we're on the wrong thread.
Last updated: Dec 20 2023 at 11:08 UTC