Zulip Chat Archive
Stream: new members
Topic: Simple proof takes 4 seconds
Vasily Ilin (Apr 28 2022 at 18:22):
I have a simple proof that consists of ext
, about 30 rewrites, and a refl
, which takes 4 seconds to elaborate. This seems excessive. Any advice on making it faster? I am also getting a (deterministic) timeout on defining an instance
that uses this proof. The timeout goes away if I do not use coassoc
. This leads me to believe that something is wrong with coassoc
. From the experimentation I've done, it seems that lean has a hard time dealing with tensor product of algebras, especially triple tensor product.
import ring_theory.tensor_product
import tactic
open_locale tensor_product
open_locale polynomial
open algebra.tensor_product
open polynomial
-- TODO variables {K : Type*} [comm_ring K]
variables (K : Type*) [comm_ring K]
set_option profiler true -- time everything
noncomputable def comul : K[X] →ₐ[K] K[X] ⊗[K] K[X] := aeval ((X ⊗ₜ 1) + (1 ⊗ₜ X))
@[simp] lemma comul_1 : comul K (1 : K[X]) = (1 ⊗ₜ 1 : K[X] ⊗[K] K[X]) :=
begin
rw alg_hom.map_one, -- ⊢ 1 = 1 ⊗ₜ[K] 1
refl,
end
@[simp] lemma comul_X : comul K X = X ⊗ₜ 1 + 1 ⊗ₜ X :=
begin
unfold comul,
rw aeval_X,
end
-- TODO convert to dot notation
lemma coassoc : (algebra.tensor_product.assoc K K[X] K[X] K[X]).to_alg_hom.comp ((map (comul K) (alg_hom.id K K[X])).comp (comul K)) = (map (alg_hom.id K K[X]) (comul K)).comp (comul K) :=
begin
ext,
rw [alg_hom.coe_comp, alg_hom.coe_comp, alg_hom.coe_comp,
function.comp_app, function.comp_app, function.comp_app,
comul_X K,
alg_hom.map_add, alg_hom.map_add, alg_hom.map_add,
map_tmul, map_tmul, map_tmul, map_tmul,
comul_X K, comul_1 K,
alg_hom.coe_id, id.def, id.def,
tensor_product.tmul_add, tensor_product.add_tmul,
alg_hom.map_add,
alg_equiv.to_alg_hom_eq_coe, alg_equiv.coe_alg_hom,
algebra.tensor_product.assoc_tmul, algebra.tensor_product.assoc_tmul, algebra.tensor_product.assoc_tmul],
refl,
end
Vasily Ilin (Apr 28 2022 at 18:23):
Posting the full file here. If you have any advice on style, a better way to structure anything, I would be grateful.
import Hopf
import ring_theory.tensor_product
import tactic
open_locale tensor_product
open_locale polynomial
open algebra.tensor_product
open polynomial
-- TODO variables {K : Type*} [comm_ring K]
variables (K : Type*) [comm_ring K]
set_option profiler true -- time everything
-- noncomputable def comm_ring.comul : K[X] →ₐ[K] K[X] ⊗[K] K[X] := aeval ((X ⊗ₜ 1) + (1 ⊗ₜ X))
noncomputable def comul : K[X] →ₐ[K] K[X] ⊗[K] K[X] := aeval ((X ⊗ₜ 1) + (1 ⊗ₜ X))
@[simp] lemma comul_1 : comul K (1 : K[X]) = (1 ⊗ₜ 1 : K[X] ⊗[K] K[X]) :=
begin
rw alg_hom.map_one, -- ⊢ 1 = 1 ⊗ₜ[K] 1
refl,
end
@[simp] lemma comul_X : comul K X = X ⊗ₜ 1 + 1 ⊗ₜ X :=
begin
unfold comul,
rw aeval_X,
end
-- TODO convert to dot notation
lemma coassoc : (algebra.tensor_product.assoc K K[X] K[X] K[X]).to_alg_hom.comp ((map (comul K) (alg_hom.id K K[X])).comp (comul K)) = (map (alg_hom.id K K[X]) (comul K)).comp (comul K) :=
begin
ext,
rw [alg_hom.coe_comp, alg_hom.coe_comp, alg_hom.coe_comp,
function.comp_app, function.comp_app, function.comp_app,
comul_X K,
alg_hom.map_add, alg_hom.map_add, alg_hom.map_add,
map_tmul, map_tmul, map_tmul, map_tmul,
comul_X K, comul_1 K,
alg_hom.coe_id, id.def, id.def,
tensor_product.tmul_add, tensor_product.add_tmul,
alg_hom.map_add,
alg_equiv.to_alg_hom_eq_coe, alg_equiv.coe_alg_hom,
algebra.tensor_product.assoc_tmul, algebra.tensor_product.assoc_tmul, algebra.tensor_product.assoc_tmul],
refl,
end
noncomputable def counit : K[X] →ₐ[K] K := aeval 0
@[simp] lemma counit_X : counit K X = 0 :=
begin
unfold counit,
simp only [coe_aeval_eq_eval, eval_X],
end
.
lemma counit_left : (algebra.tensor_product.lid K K[X]).to_alg_hom.comp ((map (counit K) (alg_hom.id K K[X])).comp (comul K)) = (alg_hom.id K K[X]) :=
begin
ext,
simp only [counit, alg_equiv.to_alg_hom_eq_coe, alg_hom.coe_comp, alg_equiv.coe_alg_hom, function.comp_app, comul_X, alg_hom.map_add, map_tmul, coe_aeval_eq_eval, eval_X, tensor_product.zero_tmul, eval_one, zero_add, lid_tmul, one_smul],
end
lemma counit_right : (algebra.tensor_product.rid K K[X]).to_alg_hom.comp ((map (alg_hom.id K K[X]) (counit K)).comp (comul K)) = (alg_hom.id K K[X]) :=
begin
ext,
simp only [counit, alg_equiv.to_alg_hom_eq_coe, alg_hom.coe_comp, alg_equiv.coe_alg_hom, function.comp_app, comul_X, _root_.map_add, map_tmul, coe_aeval_eq_eval, eval_one, eval_X, tensor_product.tmul_zero, add_zero, rid_tmul, one_smul],
end
noncomputable def coinv : K[X] →ₐ[K] K[X] := aeval (-X)
@[simp] lemma coinv_X : coinv K X = -X :=
begin
unfold coinv,
rw aeval_X,
end
lemma coinv_right : (lmul' K).comp ((map (alg_hom.id K K[X]) (coinv K)).comp (comul K)) = (algebra.of_id K K[X]).comp (counit K) :=
begin
ext,
simp only [alg_hom.coe_comp, function.comp_app, comul_X, _root_.map_add, map_tmul, alg_hom.coe_id, id.def, _root_.map_one, coinv_X, lmul'_apply_tmul, _root_.mul_one, _root_.one_mul, add_right_neg, counit_X, _root_.map_zero],
end
lemma coinv_left : (lmul' K).comp ((map (coinv K) (alg_hom.id K K[X])).comp (comul K) )= (algebra.of_id K K[X]).comp (counit K) :=
begin
ext,
simp only [alg_hom.coe_comp, function.comp_app, comul_X, _root_.map_add, map_tmul, coinv_X, alg_hom.coe_id, id.def, _root_.map_one, lmul'_apply_tmul, _root_.mul_one, _root_.one_mul, add_left_neg, counit_X, _root_.map_zero],
end
.
set_option profiler true -- time everything
noncomputable instance polynomial_hopf : hopf_algebra K K[X] := { -- TIMEOUT!
comul := comul K,
counit := counit K,
coinv := coinv K,
coassoc := coassoc K,
counit_left := counit_left K,
counit_right := counit_right K,
coinv_right := coinv_right K,
coinv_left := coinv_left K,
}
noncomputable instance polynomial_hopf : hopf_algebra K K[X] := { -- No timeout!
comul := comul K,
counit := counit K,
coinv := coinv K,
coassoc := sorry,
counit_left := counit_left K,
counit_right := counit_right K,
coinv_right := coinv_right K,
coinv_left := coinv_left K,
}
Johan Commelin (Apr 29 2022 at 03:36):
I agree that it's strange that rw
is taking such a long time.
Johan Commelin (Apr 29 2022 at 03:37):
The only unhelpful comment that I have for now, is that
apply polynomial.alg_hom_ext,
simp only [alg_hom.coe_comp, function.comp_app, map_add, map_tmul,
comul_X K, comul_1 K, alg_hom.coe_id, id.def,
tensor_product.tmul_add, tensor_product.add_tmul,
alg_equiv.to_alg_hom_eq_coe, alg_equiv.coe_alg_hom,
algebra.tensor_product.assoc_tmul, add_assoc],
is a shorter proof that takes twice as long...
Johan Commelin (Apr 29 2022 at 03:43):
Using show
to blast through some defeqs even bumps the time to 10s on my box
apply polynomial.alg_hom_ext,
show (algebra.tensor_product.assoc K K[X] K[X] K[X]) ((map (comul K) (alg_hom.id K K[X])) ((comul K) X)) =
(map (alg_hom.id K K[X]) (comul K)) ((comul K) X),
simp only [alg_hom.coe_comp, function.comp_app, map_add, map_tmul,
comul_X K, comul_1 K, alg_hom.coe_id, id.def,
tensor_product.tmul_add, tensor_product.add_tmul,
alg_equiv.to_alg_hom_eq_coe, alg_equiv.coe_alg_hom,
algebra.tensor_product.assoc_tmul, add_assoc],
Anne Baanen (Apr 29 2022 at 09:13):
Looking at the types, this might just be because Lean can become very slow in typechecking when a type has a lot of dependencies: basically, since alg_hom
, tensor_product
and polynomial
depend on the ring/module/etc structure of the arguments, and we have a type like alg_hom (tensor_product (tensor_product (polynomial _) _) _) _ _
the types grow at least with the fourth power (where quadratic is already big). And since algebra
and module
also depend on the ring structure it might even be more like to the seventh power.
Anne Baanen (Apr 29 2022 at 09:14):
I'll see if I can investigate in some more detail later today.
Jake Levinson (Apr 30 2022 at 18:07):
That's interesting. Is that something that could be made faster by some kind of additional tooling? Like adding extra functions / tactics to the algebra library to assist / direct this typechecking?
I have also found the mathlib algebra library to be quite heavy on my computer (though I haven't tried to use it too much yet).
Anne Baanen (May 02 2022 at 14:44):
It took a few days, but I finally have some time!
Anne Baanen (May 02 2022 at 14:48):
One interesting result is that replacing rw
with simp only
cuts the time in half, so perhaps a lot of time is spent in recomputing the motive (which parts of the expression stay fixed and which ones get rewritten) each time? In contrast, simp
works by simplifying each subexpression fully before going to a larger expression so I assume it can reuse more if most subexpressions don't change.
Anne Baanen (May 02 2022 at 14:56):
Also, adding map_add
to the simp only
parameters makes elaboration time go from about 500ms to 3s on my machine. Very strange...
Anne Baanen (May 02 2022 at 15:05):
Both with rw
and simp only
with set_option trace.type_context.is_def_eq_detail true
I see that unification goes up to 46 levels deep when trying to unify ⇑(?m_12.comp ?m_13) =?= ⇑((algebra.tensor_product.assoc K K[X] K[X] K[X]).to_alg_hom.comp ((map (comul K) (alg_hom.id K K[X])).comp (comul K)))
which is pretty suggestive of the types being too complicated.
Anne Baanen (May 02 2022 at 15:22):
I can't find anywhere that a strategic local attribute [irreducible]
will help, so basically the only useful suggestion I have at the moment to use simp only
instead of rw
.
Last updated: Dec 20 2023 at 11:08 UTC