|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Scott Morrison. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Scott Morrison |
| 5 | +-/ |
| 6 | +import category_theory.limits.shapes.biproducts |
| 7 | +import category_theory.preadditive |
| 8 | +import tactic.abel |
| 9 | + |
| 10 | +/-! |
| 11 | +# Basic facts about morphisms between biproducts in preadditive categories. |
| 12 | +
|
| 13 | +* In any category (with zero morphisms), if `biprod.map f g` is an isomorphism, |
| 14 | + then both `f` and `g` are isomorphisms. |
| 15 | +
|
| 16 | +The remaining lemmas hold in any preadditive category. |
| 17 | +
|
| 18 | +* If `f` is a morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism, |
| 19 | + then we can construct isomorphisms `L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂` and `R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂` |
| 20 | + so that `L.hom ≫ g ≫ R.hom` is diagonal (with `X₁ ⟶ Y₁` component still `f`), |
| 21 | + via Gaussian elimination. |
| 22 | +
|
| 23 | +* As a corollary of the previous two facts, |
| 24 | + if we have an isomorphism `X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism, |
| 25 | + we can construct an isomorphism `X₂ ≅ Y₂`. |
| 26 | +
|
| 27 | +* If `f : W ⊞ X ⟶ Y ⊞ Z` is an isomorphism, either `𝟙 W = 0`, |
| 28 | + or at least one of the component maps `W ⟶ Y` and `W ⟶ Z` is nonzero. |
| 29 | +
|
| 30 | +* If `f : ⨁ S ⟶ ⨁ T` is an isomorphism, |
| 31 | + then every column (corresponding to a nonzero summand in the domain) |
| 32 | + has some nonzero matrix entry. |
| 33 | +-/ |
| 34 | + |
| 35 | +open category_theory |
| 36 | +open category_theory.preadditive |
| 37 | +open category_theory.limits |
| 38 | + |
| 39 | +universes v u |
| 40 | + |
| 41 | +namespace category_theory |
| 42 | + |
| 43 | +variables {C : Type u} [category.{v} C] |
| 44 | +section |
| 45 | +variables [has_zero_morphisms.{v} C] [has_binary_biproducts.{v} C] |
| 46 | + |
| 47 | +/-- |
| 48 | +If |
| 49 | +``` |
| 50 | +(f 0) |
| 51 | +(0 g) |
| 52 | +``` |
| 53 | +is invertible, then `f` is invertible. |
| 54 | +-/ |
| 55 | +def is_iso_left_of_is_iso_biprod_map |
| 56 | + {W X Y Z : C} (f : W ⟶ Y) (g : X ⟶ Z) [is_iso (biprod.map f g)] : is_iso f := |
| 57 | +{ inv := biprod.inl ≫ inv (biprod.map f g) ≫ biprod.fst, |
| 58 | + hom_inv_id' := |
| 59 | + begin |
| 60 | + have t := congr_arg (λ p : W ⊞ X ⟶ W ⊞ X, biprod.inl ≫ p ≫ biprod.fst) |
| 61 | + (is_iso.hom_inv_id (biprod.map f g)), |
| 62 | + simp only [category.id_comp, category.assoc, biprod.inl_map_assoc] at t, |
| 63 | + simp [t], |
| 64 | + end, |
| 65 | + inv_hom_id' := |
| 66 | + begin |
| 67 | + have t := congr_arg (λ p : Y ⊞ Z ⟶ Y ⊞ Z, biprod.inl ≫ p ≫ biprod.fst) |
| 68 | + (is_iso.inv_hom_id (biprod.map f g)), |
| 69 | + simp only [category.id_comp, category.assoc, biprod.map_fst] at t, |
| 70 | + simp only [category.assoc], |
| 71 | + simp [t], |
| 72 | + end } |
| 73 | + |
| 74 | +/-- |
| 75 | +If |
| 76 | +``` |
| 77 | +(f 0) |
| 78 | +(0 g) |
| 79 | +``` |
| 80 | +is invertible, then `g` is invertible. |
| 81 | +-/ |
| 82 | +def is_iso_right_of_is_iso_biprod_map |
| 83 | + {W X Y Z : C} (f : W ⟶ Y) (g : X ⟶ Z) [is_iso (biprod.map f g)] : is_iso g := |
| 84 | +begin |
| 85 | + letI : is_iso (biprod.map g f) := by |
| 86 | + { rw [←biprod.braiding_map_braiding], |
| 87 | + apply_instance, }, |
| 88 | + exact is_iso_left_of_is_iso_biprod_map g f, |
| 89 | +end |
| 90 | + |
| 91 | +end |
| 92 | + |
| 93 | +section |
| 94 | +variables [preadditive.{v} C] [has_binary_biproducts.{v} C] |
| 95 | + |
| 96 | +variables {X₁ X₂ Y₁ Y₂ : C} |
| 97 | +variables (f₁₁ : X₁ ⟶ Y₁) (f₁₂ : X₁ ⟶ Y₂) (f₂₁ : X₂ ⟶ Y₁) (f₂₂ : X₂ ⟶ Y₂) |
| 98 | + |
| 99 | +/-- |
| 100 | +The "matrix" morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` with specified components. |
| 101 | +-/ |
| 102 | +def biprod.of_components : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂ := |
| 103 | +biprod.fst ≫ f₁₁ ≫ biprod.inl + |
| 104 | +biprod.fst ≫ f₁₂ ≫ biprod.inr + |
| 105 | +biprod.snd ≫ f₂₁ ≫ biprod.inl + |
| 106 | +biprod.snd ≫ f₂₂ ≫ biprod.inr |
| 107 | + |
| 108 | +@[simp] |
| 109 | +lemma biprod.inl_of_components : |
| 110 | + biprod.inl ≫ biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂ = |
| 111 | + f₁₁ ≫ biprod.inl + f₁₂ ≫ biprod.inr := |
| 112 | +by simp [biprod.of_components] |
| 113 | + |
| 114 | +@[simp] |
| 115 | +lemma biprod.inr_of_components : |
| 116 | + biprod.inr ≫ biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂ = |
| 117 | + f₂₁ ≫ biprod.inl + f₂₂ ≫ biprod.inr := |
| 118 | +by simp [biprod.of_components] |
| 119 | + |
| 120 | +@[simp] |
| 121 | +lemma biprod.of_components_fst : |
| 122 | + biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂ ≫ biprod.fst = |
| 123 | + biprod.fst ≫ f₁₁ + biprod.snd ≫ f₂₁ := |
| 124 | +by simp [biprod.of_components] |
| 125 | + |
| 126 | +@[simp] |
| 127 | +lemma biprod.of_components_snd : |
| 128 | + biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂ ≫ biprod.snd = |
| 129 | + biprod.fst ≫ f₁₂ + biprod.snd ≫ f₂₂ := |
| 130 | +by simp [biprod.of_components] |
| 131 | + |
| 132 | +@[simp] |
| 133 | +lemma biprod.of_components_eq (f : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂) : |
| 134 | + biprod.of_components (biprod.inl ≫ f ≫ biprod.fst) (biprod.inl ≫ f ≫ biprod.snd) |
| 135 | + (biprod.inr ≫ f ≫ biprod.fst) (biprod.inr ≫ f ≫ biprod.snd) = f := |
| 136 | +begin |
| 137 | + ext; simp, |
| 138 | +end |
| 139 | + |
| 140 | +@[simp] |
| 141 | +lemma biprod.of_components_comp {X₁ X₂ Y₁ Y₂ Z₁ Z₂ : C} |
| 142 | + (f₁₁ : X₁ ⟶ Y₁) (f₁₂ : X₁ ⟶ Y₂) (f₂₁ : X₂ ⟶ Y₁) (f₂₂ : X₂ ⟶ Y₂) |
| 143 | + (g₁₁ : Y₁ ⟶ Z₁) (g₁₂ : Y₁ ⟶ Z₂) (g₂₁ : Y₂ ⟶ Z₁) (g₂₂ : Y₂ ⟶ Z₂) : |
| 144 | + biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂ ≫ biprod.of_components g₁₁ g₁₂ g₂₁ g₂₂ = |
| 145 | + biprod.of_components |
| 146 | + (f₁₁ ≫ g₁₁ + f₁₂ ≫ g₂₁) (f₁₁ ≫ g₁₂ + f₁₂ ≫ g₂₂) |
| 147 | + (f₂₁ ≫ g₁₁ + f₂₂ ≫ g₂₁) (f₂₁ ≫ g₁₂ + f₂₂ ≫ g₂₂) := |
| 148 | +begin |
| 149 | + dsimp [biprod.of_components], |
| 150 | + apply biprod.hom_ext; apply biprod.hom_ext'; |
| 151 | + simp only [add_comp, comp_add, add_comp_assoc, add_zero, zero_add, |
| 152 | + biprod.inl_fst, biprod.inl_snd, biprod.inr_fst, biprod.inr_snd, |
| 153 | + biprod.inl_fst_assoc, biprod.inl_snd_assoc, biprod.inr_fst_assoc, biprod.inr_snd_assoc, |
| 154 | + has_zero_morphisms.comp_zero, has_zero_morphisms.zero_comp, has_zero_morphisms.zero_comp_assoc, |
| 155 | + category.comp_id, category.assoc], |
| 156 | +end |
| 157 | + |
| 158 | +/-- |
| 159 | +The unipotent upper triangular matrix |
| 160 | +``` |
| 161 | +(1 r) |
| 162 | +(0 1) |
| 163 | +``` |
| 164 | +as an isomorphism. |
| 165 | +-/ |
| 166 | +@[simps] |
| 167 | +def biprod.unipotent_upper {X₁ X₂ : C} (r : X₁ ⟶ X₂) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ := |
| 168 | +{ hom := biprod.of_components (𝟙 _) r 0 (𝟙 _), |
| 169 | + inv := biprod.of_components (𝟙 _) (-r) 0 (𝟙 _), } |
| 170 | + |
| 171 | +/-- |
| 172 | +The unipotent lower triangular matrix |
| 173 | +``` |
| 174 | +(1 0) |
| 175 | +(r 1) |
| 176 | +``` |
| 177 | +as an isomorphism. |
| 178 | +-/ |
| 179 | +@[simps] |
| 180 | +def biprod.unipotent_lower {X₁ X₂ : C} (r : X₂ ⟶ X₁) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ := |
| 181 | +{ hom := biprod.of_components (𝟙 _) 0 r (𝟙 _), |
| 182 | + inv := biprod.of_components (𝟙 _) 0 (-r) (𝟙 _), } |
| 183 | + |
| 184 | +/-- |
| 185 | +If `f` is a morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism, |
| 186 | +then we can construct isomorphisms `L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂` and `R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂` |
| 187 | +so that `L.hom ≫ g ≫ R.hom` is diagonal (with `X₁ ⟶ Y₁` component still `f`), |
| 188 | +via Gaussian elimination. |
| 189 | +
|
| 190 | +(This is the version of `biprod.gaussian` written in terms of components.) |
| 191 | +-/ |
| 192 | +def biprod.gaussian' [is_iso f₁₁] : |
| 193 | + Σ' (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) (g₂₂ : X₂ ⟶ Y₂), |
| 194 | + L.hom ≫ (biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂) ≫ R.hom = biprod.map f₁₁ g₂₂ := |
| 195 | +⟨biprod.unipotent_lower (-(f₂₁ ≫ inv f₁₁)), |
| 196 | + biprod.unipotent_upper (-(inv f₁₁ ≫ f₁₂)), |
| 197 | + f₂₂ - f₂₁ ≫ (inv f₁₁) ≫ f₁₂, |
| 198 | + by ext; simp; abel⟩ |
| 199 | + |
| 200 | +/-- |
| 201 | +If `f` is a morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism, |
| 202 | +then we can construct isomorphisms `L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂` and `R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂` |
| 203 | +so that `L.hom ≫ g ≫ R.hom` is diagonal (with `X₁ ⟶ Y₁` component still `f`), |
| 204 | +via Gaussian elimination. |
| 205 | +-/ |
| 206 | +def biprod.gaussian (f : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂) [is_iso (biprod.inl ≫ f ≫ biprod.fst)] : |
| 207 | + Σ' (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) (g₂₂ : X₂ ⟶ Y₂), |
| 208 | + L.hom ≫ f ≫ R.hom = biprod.map (biprod.inl ≫ f ≫ biprod.fst) g₂₂ := |
| 209 | +begin |
| 210 | + let := biprod.gaussian' |
| 211 | + (biprod.inl ≫ f ≫ biprod.fst) (biprod.inl ≫ f ≫ biprod.snd) |
| 212 | + (biprod.inr ≫ f ≫ biprod.fst) (biprod.inr ≫ f ≫ biprod.snd), |
| 213 | + simpa [biprod.of_components_eq], |
| 214 | +end |
| 215 | + |
| 216 | +/-- |
| 217 | +If `X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂` via a two-by-two matrix whose `X₁ ⟶ Y₁` entry is an isomorphism, |
| 218 | +then we can construct an isomorphism `X₂ ≅ Y₂`, via Gaussian elimination. |
| 219 | +-/ |
| 220 | +def biprod.iso_elim' [is_iso f₁₁] [is_iso (biprod.of_components f₁₁ f₁₂ f₂₁ f₂₂)] : X₂ ≅ Y₂ := |
| 221 | +begin |
| 222 | + obtain ⟨L, R, g, w⟩ := biprod.gaussian' f₁₁ f₁₂ f₂₁ f₂₂, |
| 223 | + letI : is_iso (biprod.map f₁₁ g) := by { rw ←w, apply_instance, }, |
| 224 | + letI : is_iso g := (is_iso_right_of_is_iso_biprod_map f₁₁ g), |
| 225 | + exact as_iso g, |
| 226 | +end |
| 227 | + |
| 228 | +/-- |
| 229 | +If `f` is an isomorphism `X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism, |
| 230 | +then we can construct an isomorphism `X₂ ≅ Y₂`, via Gaussian elimination. |
| 231 | +-/ |
| 232 | +def biprod.iso_elim (f : X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂) [is_iso (biprod.inl ≫ f.hom ≫ biprod.fst)] : X₂ ≅ Y₂ := |
| 233 | +begin |
| 234 | + letI : is_iso (biprod.of_components |
| 235 | + (biprod.inl ≫ f.hom ≫ biprod.fst) |
| 236 | + (biprod.inl ≫ f.hom ≫ biprod.snd) |
| 237 | + (biprod.inr ≫ f.hom ≫ biprod.fst) |
| 238 | + (biprod.inr ≫ f.hom ≫ biprod.snd)) := |
| 239 | + by { simp only [biprod.of_components_eq], apply_instance, }, |
| 240 | + exact biprod.iso_elim' |
| 241 | + (biprod.inl ≫ f.hom ≫ biprod.fst) |
| 242 | + (biprod.inl ≫ f.hom ≫ biprod.snd) |
| 243 | + (biprod.inr ≫ f.hom ≫ biprod.fst) |
| 244 | + (biprod.inr ≫ f.hom ≫ biprod.snd) |
| 245 | +end |
| 246 | + |
| 247 | +lemma biprod.column_nonzero_of_iso {W X Y Z : C} |
| 248 | + (f : W ⊞ X ⟶ Y ⊞ Z) [is_iso f] : |
| 249 | + 𝟙 W = 0 ∨ biprod.inl ≫ f ≫ biprod.fst ≠ 0 ∨ biprod.inl ≫ f ≫ biprod.snd ≠ 0 := |
| 250 | +begin |
| 251 | + classical, |
| 252 | + by_contradiction, |
| 253 | + rw [not_or_distrib, not_or_distrib, classical.not_not, classical.not_not] at a, |
| 254 | + rcases a with ⟨nz, a₁, a₂⟩, |
| 255 | + set x := biprod.inl ≫ f ≫ inv f ≫ biprod.fst, |
| 256 | + have h₁ : x = 𝟙 W, by simp [x], |
| 257 | + have h₀ : x = 0, |
| 258 | + { dsimp [x], |
| 259 | + rw [←category.id_comp (inv f), category.assoc, ←biprod.total], |
| 260 | + conv_lhs { slice 2 3, rw [comp_add], }, |
| 261 | + simp only [category.assoc], |
| 262 | + rw [comp_add_assoc, add_comp], |
| 263 | + conv_lhs { congr, skip, slice 1 3, rw a₂, }, |
| 264 | + simp only [has_zero_morphisms.zero_comp, add_zero], |
| 265 | + conv_lhs { slice 1 3, rw a₁, }, |
| 266 | + simp only [has_zero_morphisms.zero_comp], }, |
| 267 | + exact nz (h₁.symm.trans h₀), |
| 268 | +end |
| 269 | + |
| 270 | + |
| 271 | +end |
| 272 | + |
| 273 | +variables [preadditive.{v} C] |
| 274 | + |
| 275 | +lemma biproduct.column_nonzero_of_iso' |
| 276 | + {σ τ : Type v} [decidable_eq σ] [decidable_eq τ] [fintype τ] |
| 277 | + {S : σ → C} [has_biproduct.{v} S] {T : τ → C} [has_biproduct.{v} T] |
| 278 | + (s : σ) (f : ⨁ S ⟶ ⨁ T) [is_iso f] : |
| 279 | + (∀ t : τ, biproduct.ι S s ≫ f ≫ biproduct.π T t = 0) → 𝟙 (S s) = 0 := |
| 280 | +begin |
| 281 | + intro z, |
| 282 | + set x := biproduct.ι S s ≫ f ≫ inv f ≫ biproduct.π S s, |
| 283 | + have h₁ : x = 𝟙 (S s), by simp [x], |
| 284 | + have h₀ : x = 0, |
| 285 | + { dsimp [x], |
| 286 | + rw [←category.id_comp (inv f), category.assoc, ←biproduct.total], |
| 287 | + simp only [comp_sum_assoc], |
| 288 | + conv_lhs { congr, apply_congr, skip, simp only [reassoc_of z], }, |
| 289 | + simp, }, |
| 290 | + exact h₁.symm.trans h₀, |
| 291 | +end |
| 292 | + |
| 293 | +/-- |
| 294 | +If `f : ⨁ S ⟶ ⨁ T` is an isomorphism, and `s` is a non-trivial summand of the source, |
| 295 | +then there is some `t` in the target so that the `s, t` matrix entry of `f` is nonzero. |
| 296 | +-/ |
| 297 | +def biproduct.column_nonzero_of_iso |
| 298 | + {σ τ : Type v} [decidable_eq σ] [decidable_eq τ] [fintype τ] |
| 299 | + {S : σ → C} [has_biproduct.{v} S] {T : τ → C} [has_biproduct.{v} T] |
| 300 | + (s : σ) (nz : 𝟙 (S s) ≠ 0) |
| 301 | + [∀ t, decidable_eq (S s ⟶ T t)] |
| 302 | + (f : ⨁ S ⟶ ⨁ T) [is_iso f] : |
| 303 | + trunc (Σ' t : τ, biproduct.ι S s ≫ f ≫ biproduct.π T t ≠ 0) := |
| 304 | +begin |
| 305 | + apply trunc_sigma_of_exists, |
| 306 | + -- Do this before we run `classical`, so we get the right `decidable_eq` instances. |
| 307 | + have t := biproduct.column_nonzero_of_iso'.{v} s f, |
| 308 | + classical, |
| 309 | + by_contradiction, |
| 310 | + simp only [classical.not_exists_not] at a, |
| 311 | + exact nz (t a) |
| 312 | +end |
| 313 | + |
| 314 | +end category_theory |
0 commit comments