Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 6623e6a

Browse files
committed
fix(*): add missing classical tactics and decidable arguments (#18277)
As discussed in [this Zulip thread](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/.60classical.60.20attribute.20leakage/near/282726128), the `classical` tactic is buggy in Mathlib3, and "leaks" into subsequent declarations. This doesn't port well, as the bug is fixed in lean 4. This PR installs a temporary hack to contain these leaks, fixes all of the correponding breakages, then reverts the hack. The result is that the new `classical` tactics in the diff are not needed in Lean 3, but will be needed in Lean 4. In a future PR, I will try committing the hack itself; but in the meantime, these files are very close to (if not beyond) the port, so the sooner they are fixed the better.
1 parent a81201c commit 6623e6a

File tree

27 files changed

+121
-64
lines changed

27 files changed

+121
-64
lines changed

src/algebra/direct_sum/basic.lean

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,20 @@ noncomputable def sigma_curry : (⨁ (i : Σ i, _), δ i.1 i.2) →+ ⨁ i j, δ
230230

231231
/--The natural map between `⨁ i (j : α i), δ i j` and `Π₀ (i : Σ i, α i), δ i.1 i.2`, inverse of
232232
`curry`.-/
233-
noncomputable def sigma_uncurry : (⨁ i j, δ i j) →+ ⨁ (i : Σ i, _), δ i.1 i.2 :=
233+
def sigma_uncurry [Π i, decidable_eq (α i)] [Π i j, decidable_eq (δ i j)] :
234+
(⨁ i j, δ i j) →+ ⨁ (i : Σ i, _), δ i.1 i.2 :=
234235
{ to_fun := dfinsupp.sigma_uncurry,
235236
map_zero' := dfinsupp.sigma_uncurry_zero,
236237
map_add' := dfinsupp.sigma_uncurry_add }
237238

238-
@[simp] lemma sigma_uncurry_apply (f : ⨁ i j, δ i j) (i : ι) (j : α i) :
239+
@[simp] lemma sigma_uncurry_apply [Π i, decidable_eq (α i)] [Π i j, decidable_eq (δ i j)]
240+
(f : ⨁ i j, δ i j) (i : ι) (j : α i) :
239241
sigma_uncurry f ⟨i, j⟩ = f i j := dfinsupp.sigma_uncurry_apply f i j
240242

241243
/--The natural map between `⨁ (i : Σ i, α i), δ i.1 i.2` and `⨁ i (j : α i), δ i j`.-/
242-
noncomputable def sigma_curry_equiv : (⨁ (i : Σ i, _), δ i.1 i.2) ≃+ ⨁ i j, δ i j :=
244+
noncomputable def sigma_curry_equiv
245+
[Π i, decidable_eq (α i)] [Π i j, decidable_eq (δ i j)] :
246+
(⨁ (i : Σ i, _), δ i.1 i.2) ≃+ ⨁ i j, δ i j :=
243247
{ ..sigma_curry, ..dfinsupp.sigma_curry_equiv }
244248

245249
end sigma

src/algebra/direct_sum/module.lean

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,19 @@ noncomputable def sigma_lcurry : (⨁ (i : Σ i, _), δ i.1 i.2) →ₗ[R] ⨁ i
222222
sigma_lcurry R f i j = f ⟨i, j⟩ := sigma_curry_apply f i j
223223

224224
/--`uncurry` as a linear map.-/
225-
noncomputable def sigma_luncurry : (⨁ i j, δ i j) →ₗ[R] ⨁ (i : Σ i, _), δ i.1 i.2 :=
225+
def sigma_luncurry [Π i, decidable_eq (α i)] [Π i j, decidable_eq (δ i j)] :
226+
(⨁ i j, δ i j) →ₗ[R] ⨁ (i : Σ i, _), δ i.1 i.2 :=
226227
{ map_smul' := dfinsupp.sigma_uncurry_smul,
227228
..sigma_uncurry }
228229

229-
@[simp] lemma sigma_luncurry_apply (f : ⨁ i j, δ i j) (i : ι) (j : α i) :
230+
@[simp] lemma sigma_luncurry_apply [Π i, decidable_eq (α i)] [Π i j, decidable_eq (δ i j)]
231+
(f : ⨁ i j, δ i j) (i : ι) (j : α i) :
230232
sigma_luncurry R f ⟨i, j⟩ = f i j := sigma_uncurry_apply f i j
231233

232234
/--`curry_equiv` as a linear equiv.-/
233-
noncomputable def sigma_lcurry_equiv : (⨁ (i : Σ i, _), δ i.1 i.2) ≃ₗ[R] ⨁ i j, δ i j :=
235+
noncomputable def sigma_lcurry_equiv
236+
[Π i, decidable_eq (α i)] [Π i j, decidable_eq (δ i j)] :
237+
(⨁ (i : Σ i, _), δ i.1 i.2) ≃ₗ[R] ⨁ i j, δ i j :=
234238
{ ..sigma_curry_equiv, ..sigma_lcurry R }
235239

236240
end sigma

src/algebra/free_algebra.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ map_eq_one_iff (algebra_map _ _) algebra_map_left_inverse.injective
344344

345345
-- this proof is copied from the approach in `free_abelian_group.of_injective`
346346
lemma ι_injective [nontrivial R] : function.injective (ι R : X → free_algebra R X) :=
347-
λ x y hoxy, classical.by_contradiction $ assume hxy : x ≠ y,
347+
λ x y hoxy, classical.by_contradiction $ by classical; exact assume hxy : x ≠ y,
348348
let f : free_algebra R X →ₐ[R] R :=
349-
lift R (λ z, by classical; exact if x = z then (1 : R) else 0) in
349+
lift R (λ z, if x = z then (1 : R) else 0) in
350350
have hfx1 : f (ι R x) = 1, from (lift_ι_apply _ _).trans $ if_pos rfl,
351351
have hfy1 : f (ι R y) = 1, from hoxy ▸ hfx1,
352352
have hfy0 : f (ι R y) = 0, from (lift_ι_apply _ _).trans $ if_neg hxy,

src/algebra/module/pid.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ begin
213213
haveI := λ i, is_noetherian_submodule' (torsion_by R N $ p i ^ e i),
214214
exact λ i, torsion_by_prime_power_decomposition (hp i)
215215
((is_torsion'_powers_iff $ p i).mpr $ λ x, ⟨e i, smul_torsion_by _ _⟩) },
216+
classical,
216217
refine ⟨Σ i, fin (this i).some, infer_instance,
217218
λ ⟨i, j⟩, p i, λ ⟨i, j⟩, hp i, λ ⟨i, j⟩, (this i).some_spec.some j,
218219
⟨(linear_equiv.of_bijective (direct_sum.coe_linear_map _) h).symm.trans $

src/algebra/monoid_algebra/basic.lean

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ end
330330
lemma mul_apply_antidiagonal [has_mul G] (f g : monoid_algebra k G) (x : G) (s : finset (G × G))
331331
(hs : ∀ {p : G × G}, p ∈ s ↔ p.1 * p.2 = x) :
332332
(f * g) x = ∑ p in s, (f p.1 * g p.2) :=
333-
let F : G × G → k := λ p, by classical; exact if p.1 * p.2 = x then f p.1 * g p.2 else 0 in
333+
by classical; exact
334+
let F : G × G → k := λ p, if p.1 * p.2 = x then f p.1 * g p.2 else 0 in
334335
calc (f * g) x = (∑ a₁ in f.support, ∑ a₂ in g.support, F (a₁, a₂)) :
335336
mul_apply f g x
336337
... = ∑ p in f.support ×ˢ g.support, F p : finset.sum_product.symm
@@ -477,8 +478,8 @@ end⟩
477478
also commute with the algebra multiplication. -/
478479
instance smul_comm_class_self [smul_comm_class R k k] :
479480
smul_comm_class R (monoid_algebra k G) (monoid_algebra k G) :=
480-
⟨λ t a b,
481-
begin
481+
⟨λ t a b, begin
482+
classical,
482483
ext m,
483484
simp only [mul_apply, finsupp.sum, finset.smul_sum, smul_ite, mul_smul_comm, sum_smul_index',
484485
implies_true_iff, eq_self_iff_true, coe_smul, ite_eq_right_iff, smul_eq_mul, pi.smul_apply,

src/algebraic_geometry/elliptic_curve/weierstrass.lean

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,18 +433,25 @@ instance : is_scalar_tower R R[X] W.coordinate_ring := ideal.quotient.is_scalar_
433433

434434
instance [subsingleton R] : subsingleton W.coordinate_ring := module.subsingleton R[X] _
435435

436+
section
437+
open_locale classical
436438
/-- The basis $\{1, Y\}$ for the coordinate ring $R[W]$ over the polynomial ring $R[X]$.
437439
438440
Given a Weierstrass curve `W`, write `W^.coordinate_ring.basis` for this basis. -/
439441
protected noncomputable def basis : basis (fin 2) R[X] W.coordinate_ring :=
440442
(subsingleton_or_nontrivial R).by_cases (λ _, by exactI default) $ λ _, by exactI
441443
(basis.reindex (adjoin_root.power_basis' W.monic_polynomial).basis $
442444
fin_congr $ W.nat_degree_polynomial)
445+
end
443446

444447
lemma basis_apply (n : fin 2) :
445448
W^.coordinate_ring.basis n = (adjoin_root.power_basis' W.monic_polynomial).gen ^ (n : ℕ) :=
446-
by { nontriviality R, simpa only [coordinate_ring.basis, or.by_cases, dif_neg (not_subsingleton R),
447-
basis.reindex_apply, power_basis.basis_eq_pow] }
449+
begin
450+
classical,
451+
nontriviality R,
452+
simpa only [coordinate_ring.basis, or.by_cases, dif_neg (not_subsingleton R),
453+
basis.reindex_apply, power_basis.basis_eq_pow]
454+
end
448455

449456
lemma basis_zero : W^.coordinate_ring.basis 0 = 1 := by simpa only [basis_apply] using pow_zero _
450457

src/analysis/inner_product_space/orientation.lean

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ lemma volume_form_robust (b : orthonormal_basis (fin n) ℝ E) (hb : b.to_basis.
213213
o.volume_form = b.to_basis.det :=
214214
begin
215215
unfreezingI { cases n },
216-
{ have : o = positive_orientation := hb.symm.trans b.to_basis.orientation_is_empty,
216+
{ classical,
217+
have : o = positive_orientation := hb.symm.trans b.to_basis.orientation_is_empty,
217218
simp [volume_form, or.by_cases, dif_pos this] },
218219
{ dsimp [volume_form],
219220
rw [same_orientation_iff_det_eq_det, hb],
@@ -227,7 +228,8 @@ lemma volume_form_robust_neg (b : orthonormal_basis (fin n) ℝ E)
227228
o.volume_form = - b.to_basis.det :=
228229
begin
229230
unfreezingI { cases n },
230-
{ have : positive_orientation ≠ o := by rwa b.to_basis.orientation_is_empty at hb,
231+
{ classical,
232+
have : positive_orientation ≠ o := by rwa b.to_basis.orientation_is_empty at hb,
231233
simp [volume_form, or.by_cases, dif_neg this.symm] },
232234
let e : orthonormal_basis (fin n.succ) ℝ E := o.fin_orthonormal_basis n.succ_pos (fact.out _),
233235
dsimp [volume_form],
@@ -239,7 +241,7 @@ end
239241
@[simp] lemma volume_form_neg_orientation : (-o).volume_form = - o.volume_form :=
240242
begin
241243
unfreezingI { cases n },
242-
{ refine o.eq_or_eq_neg_of_is_empty.by_cases _ _; rintros rfl; simp [volume_form_zero_neg] },
244+
{ refine o.eq_or_eq_neg_of_is_empty.elim _ _; rintros rfl; simp [volume_form_zero_neg] },
243245
let e : orthonormal_basis (fin n.succ) ℝ E := o.fin_orthonormal_basis n.succ_pos (fact.out _),
244246
have h₁ : e.to_basis.orientation = o := o.fin_orthonormal_basis_orientation _ _,
245247
have h₂ : e.to_basis.orientation ≠ -o,
@@ -252,7 +254,7 @@ lemma volume_form_robust' (b : orthonormal_basis (fin n) ℝ E) (v : fin n → E
252254
|o.volume_form v| = |b.to_basis.det v| :=
253255
begin
254256
unfreezingI { cases n },
255-
{ refine o.eq_or_eq_neg_of_is_empty.by_cases _ _; rintros rfl; simp },
257+
{ refine o.eq_or_eq_neg_of_is_empty.elim _ _; rintros rfl; simp },
256258
{ rw [o.volume_form_robust (b.adjust_to_orientation o) (b.orientation_adjust_to_orientation o),
257259
b.abs_det_adjust_to_orientation] },
258260
end
@@ -263,7 +265,7 @@ value by the product of the norms of the vectors `v i`. -/
263265
lemma abs_volume_form_apply_le (v : fin n → E) : |o.volume_form v| ≤ ∏ i : fin n, ‖v i‖ :=
264266
begin
265267
unfreezingI { cases n },
266-
{ refine o.eq_or_eq_neg_of_is_empty.by_cases _ _; rintros rfl; simp },
268+
{ refine o.eq_or_eq_neg_of_is_empty.elim _ _; rintros rfl; simp },
267269
haveI : finite_dimensional ℝ E := fact_finite_dimensional_of_finrank_eq_succ n,
268270
have : finrank ℝ E = fintype.card (fin n.succ) := by simpa using _i.out,
269271
let b : orthonormal_basis (fin n.succ) ℝ E := gram_schmidt_orthonormal_basis this v,
@@ -288,7 +290,7 @@ lemma abs_volume_form_apply_of_pairwise_orthogonal
288290
|o.volume_form v| = ∏ i : fin n, ‖v i‖ :=
289291
begin
290292
unfreezingI { cases n },
291-
{ refine o.eq_or_eq_neg_of_is_empty.by_cases _ _; rintros rfl; simp },
293+
{ refine o.eq_or_eq_neg_of_is_empty.elim _ _; rintros rfl; simp },
292294
haveI : finite_dimensional ℝ E := fact_finite_dimensional_of_finrank_eq_succ n,
293295
have hdim : finrank ℝ E = fintype.card (fin n.succ) := by simpa using _i.out,
294296
let b : orthonormal_basis (fin n.succ) ℝ E := gram_schmidt_orthonormal_basis hdim v,
@@ -320,7 +322,7 @@ lemma volume_form_map {F : Type*} [inner_product_space ℝ F] [fact (finrank ℝ
320322
(orientation.map (fin n) φ.to_linear_equiv o).volume_form x = o.volume_form (φ.symm ∘ x) :=
321323
begin
322324
unfreezingI { cases n },
323-
{ refine o.eq_or_eq_neg_of_is_empty.by_cases _ _; rintros rfl; simp },
325+
{ refine o.eq_or_eq_neg_of_is_empty.elim _ _; rintros rfl; simp },
324326
let e : orthonormal_basis (fin n.succ) ℝ E := o.fin_orthonormal_basis n.succ_pos (fact.out _),
325327
have he : e.to_basis.orientation = o :=
326328
(o.fin_orthonormal_basis_orientation n.succ_pos (fact.out _)),

src/analysis/inner_product_space/pi_L2.lean

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ basis.of_equiv_fun b.repr.to_linear_equiv
296296
begin
297297
change ⇑(basis.of_equiv_fun b.repr.to_linear_equiv) = b,
298298
ext j,
299+
classical,
299300
rw basis.coe_of_equiv_fun,
300301
congr,
301302
end
@@ -402,7 +403,7 @@ protected lemma coe_mk (hon : orthonormal 𝕜 v) (hsp: ⊤ ≤ submodule.span
402403
by classical; rw [orthonormal_basis.mk, _root_.basis.coe_to_orthonormal_basis, basis.coe_mk]
403404

404405
/-- Any finite subset of a orthonormal family is an `orthonormal_basis` for its span. -/
405-
protected def span {v' : ι' → E} (h : orthonormal 𝕜 v') (s : finset ι') :
406+
protected def span [decidable_eq E] {v' : ι' → E} (h : orthonormal 𝕜 v') (s : finset ι') :
406407
orthonormal_basis s 𝕜 (span 𝕜 (s.image v' : set E)) :=
407408
let
408409
e₀' : basis s 𝕜 _ := basis.span (h.linear_independent.comp (coe : s → ι') subtype.coe_injective),
@@ -421,7 +422,8 @@ let
421422
in
422423
e₀.map φ.symm
423424

424-
@[simp] protected lemma span_apply {v' : ι' → E} (h : orthonormal 𝕜 v') (s : finset ι') (i : s) :
425+
@[simp] protected lemma span_apply [decidable_eq E]
426+
{v' : ι' → E} (h : orthonormal 𝕜 v') (s : finset ι') (i : s) :
425427
(orthonormal_basis.span h s i : E) = v' i :=
426428
by simp only [orthonormal_basis.span, basis.span_apply, linear_isometry_equiv.of_eq_symm,
427429
orthonormal_basis.map_apply, orthonormal_basis.coe_mk,

src/combinatorics/simple_graph/basic.lean

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -606,13 +606,16 @@ attribute [mono] edge_finset_mono edge_finset_strict_mono
606606

607607
@[simp] lemma edge_finset_bot : (⊥ : simple_graph V).edge_finset = ∅ := by simp [edge_finset]
608608

609-
@[simp] lemma edge_finset_sup : (G₁ ⊔ G₂).edge_finset = G₁.edge_finset ∪ G₂.edge_finset :=
609+
@[simp] lemma edge_finset_sup [decidable_eq V] :
610+
(G₁ ⊔ G₂).edge_finset = G₁.edge_finset ∪ G₂.edge_finset :=
610611
by simp [edge_finset]
611612

612-
@[simp] lemma edge_finset_inf : (G₁ ⊓ G₂).edge_finset = G₁.edge_finset ∩ G₂.edge_finset :=
613+
@[simp] lemma edge_finset_inf [decidable_eq V] :
614+
(G₁ ⊓ G₂).edge_finset = G₁.edge_finset ∩ G₂.edge_finset :=
613615
by simp [edge_finset]
614616

615-
@[simp] lemma edge_finset_sdiff : (G₁ \ G₂).edge_finset = G₁.edge_finset \ G₂.edge_finset :=
617+
@[simp] lemma edge_finset_sdiff [decidable_eq V] :
618+
(G₁ \ G₂).edge_finset = G₁.edge_finset \ G₂.edge_finset :=
616619
by simp [edge_finset]
617620

618621
lemma edge_finset_card : G.edge_finset.card = fintype.card G.edge_set := set.to_finset_card _

src/data/dfinsupp/basic.lean

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,8 @@ begin
12211221
sigma_curry_apply, smul_apply]
12221222
end
12231223

1224-
@[simp] lemma sigma_curry_single [Π i j, has_zero (δ i j)] (ij : Σ i, α i) (x : δ ij.1 ij.2) :
1224+
@[simp] lemma sigma_curry_single [decidable_eq ι] [Π i, decidable_eq (α i)]
1225+
[Π i j, has_zero (δ i j)] (ij : Σ i, α i) (x : δ ij.1 ij.2) :
12251226
@sigma_curry _ _ _ _ (single ij x) = single ij.1 (single ij.2 x : Π₀ j, δ ij.1 j) :=
12261227
begin
12271228
obtain ⟨i, j⟩ := ij,
@@ -1240,7 +1241,8 @@ end
12401241

12411242
/--The natural map between `Π₀ i (j : α i), δ i j` and `Π₀ (i : Σ i, α i), δ i.1 i.2`, inverse of
12421243
`curry`.-/
1243-
noncomputable def sigma_uncurry [Π i j, has_zero (δ i j)] (f : Π₀ i j, δ i j) :
1244+
def sigma_uncurry [Π i j, has_zero (δ i j)]
1245+
[Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)] (f : Π₀ i j, δ i j) :
12441246
Π₀ (i : Σ i, _), δ i.1 i.2 :=
12451247
{ to_fun := λ i, f i.1 i.2,
12461248
support' := f.support'.map $ λ s,
@@ -1255,24 +1257,32 @@ noncomputable def sigma_uncurry [Π i j, has_zero (δ i j)] (f : Π₀ i j, δ i
12551257
rw [hi, zero_apply] }
12561258
end⟩ }
12571259

1258-
@[simp] lemma sigma_uncurry_apply [Π i j, has_zero (δ i j)] (f : Π₀ i j, δ i j) (i : ι) (j : α i) :
1260+
@[simp] lemma sigma_uncurry_apply [Π i j, has_zero (δ i j)]
1261+
[Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)]
1262+
(f : Π₀ i j, δ i j) (i : ι) (j : α i) :
12591263
sigma_uncurry f ⟨i, j⟩ = f i j :=
12601264
rfl
12611265

1262-
@[simp] lemma sigma_uncurry_zero [Π i j, has_zero (δ i j)] :
1266+
@[simp] lemma sigma_uncurry_zero [Π i j, has_zero (δ i j)]
1267+
[Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)]:
12631268
sigma_uncurry (0 : Π₀ i j, δ i j) = 0 :=
12641269
rfl
12651270

1266-
@[simp] lemma sigma_uncurry_add [Π i j, add_zero_class (δ i j)] (f g : Π₀ i j, δ i j) :
1271+
@[simp] lemma sigma_uncurry_add [Π i j, add_zero_class (δ i j)]
1272+
[Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)]
1273+
(f g : Π₀ i j, δ i j) :
12671274
sigma_uncurry (f + g) = sigma_uncurry f + sigma_uncurry g :=
12681275
coe_fn_injective rfl
12691276

12701277
@[simp] lemma sigma_uncurry_smul [monoid γ] [Π i j, add_monoid (δ i j)]
1278+
[Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)]
12711279
[Π i j, distrib_mul_action γ (δ i j)] (r : γ) (f : Π₀ i j, δ i j) :
12721280
sigma_uncurry (r • f) = r • sigma_uncurry f :=
12731281
coe_fn_injective rfl
12741282

1275-
@[simp] lemma sigma_uncurry_single [Π i j, has_zero (δ i j)] (i) (j : α i) (x : δ i j) :
1283+
@[simp] lemma sigma_uncurry_single [Π i j, has_zero (δ i j)]
1284+
[decidable_eq ι] [Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)]
1285+
(i) (j : α i) (x : δ i j) :
12761286
sigma_uncurry (single i (single j x : Π₀ (j : α i), δ i j)) = single ⟨i, j⟩ x:=
12771287
begin
12781288
ext ⟨i', j'⟩,
@@ -1291,7 +1301,8 @@ end
12911301
/--The natural bijection between `Π₀ (i : Σ i, α i), δ i.1 i.2` and `Π₀ i (j : α i), δ i j`.
12921302
12931303
This is the dfinsupp version of `equiv.Pi_curry`. -/
1294-
noncomputable def sigma_curry_equiv [Π i j, has_zero (δ i j)] :
1304+
noncomputable def sigma_curry_equiv [Π i j, has_zero (δ i j)]
1305+
[Π i, decidable_eq (α i)] [Π i j (x : δ i j), decidable (x ≠ 0)] :
12951306
(Π₀ (i : Σ i, _), δ i.1 i.2) ≃ Π₀ i j, δ i j :=
12961307
{ to_fun := sigma_curry,
12971308
inv_fun := sigma_uncurry,

0 commit comments

Comments
 (0)