|
| 1 | +/- |
| 2 | +Copyright (c) 2021 Yakov Pechersky. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yakov Pechersky |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module logic.equiv.fintype |
| 7 | +! leanprover-community/mathlib commit 9407b03373c8cd201df99d6bc5514fc2db44054f |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Data.Fintype.Basic |
| 12 | +import Mathlib.GroupTheory.Perm.Sign |
| 13 | +import Mathlib.Logic.Equiv.Defs |
| 14 | + |
| 15 | +/-! # Equivalence between fintypes |
| 16 | +
|
| 17 | +This file contains some basic results on equivalences where one or both |
| 18 | +sides of the equivalence are `Fintype`s. |
| 19 | +
|
| 20 | +# Main definitions |
| 21 | +
|
| 22 | + - `Function.Embedding.toEquivRange`: computably turn an embedding of a |
| 23 | + fintype into an `Equiv` of the domain to its range |
| 24 | + - `Equiv.Perm.viaFintypeEmbedding : Perm α → (α ↪ β) → Perm β` extends the domain of |
| 25 | + a permutation, fixing everything outside the range of the embedding |
| 26 | +
|
| 27 | +# Implementation details |
| 28 | +
|
| 29 | + - `Function.Embedding.toEquivRange` uses a computable inverse, but one that has poor |
| 30 | + computational performance, since it operates by exhaustive search over the input `Fintype`s. |
| 31 | +-/ |
| 32 | + |
| 33 | + |
| 34 | +variable {α β : Type _} [Fintype α] [DecidableEq β] (e : Equiv.Perm α) (f : α ↪ β) |
| 35 | + |
| 36 | +/-- Computably turn an embedding `f : α ↪ β` into an equiv `α ≃ Set.range f`, |
| 37 | +if `α` is a `Fintype`. Has poor computational performance, due to exhaustive searching in |
| 38 | +constructed inverse. When a better inverse is known, use `Equiv.ofLeftInverse'` or |
| 39 | +`Equiv.ofLeftInverse` instead. This is the computable version of `Equiv.ofInjective`. |
| 40 | +-/ |
| 41 | +def Function.Embedding.toEquivRange : α ≃ Set.range f := |
| 42 | + ⟨fun a => ⟨f a, Set.mem_range_self a⟩, f.invOfMemRange, fun _ => by simp, fun _ => by simp⟩ |
| 43 | +#align function.embedding.to_equiv_range Function.Embedding.toEquivRange |
| 44 | + |
| 45 | +@[simp] |
| 46 | +theorem Function.Embedding.toEquivRange_apply (a : α) : |
| 47 | + f.toEquivRange a = ⟨f a, Set.mem_range_self a⟩ := |
| 48 | + rfl |
| 49 | +#align function.embedding.to_equiv_range_apply Function.Embedding.toEquivRange_apply |
| 50 | + |
| 51 | +@[simp] |
| 52 | +theorem Function.Embedding.toEquivRange_symm_apply_self (a : α) : |
| 53 | + f.toEquivRange.symm ⟨f a, Set.mem_range_self a⟩ = a := by simp [Equiv.symm_apply_eq] |
| 54 | +#align function.embedding.to_equiv_range_symm_apply_self Function.Embedding.toEquivRange_symm_apply_self |
| 55 | + |
| 56 | +theorem Function.Embedding.toEquivRange_eq_ofInjective : |
| 57 | + f.toEquivRange = Equiv.ofInjective f f.injective := by |
| 58 | + ext |
| 59 | + simp |
| 60 | +#align function.embedding.to_equiv_range_eq_of_injective Function.Embedding.toEquivRange_eq_ofInjective |
| 61 | + |
| 62 | +/-- Extend the domain of `e : Equiv.Perm α`, mapping it through `f : α ↪ β`. |
| 63 | +Everything outside of `Set.range f` is kept fixed. Has poor computational performance, |
| 64 | +due to exhaustive searching in constructed inverse due to using `Function.Embedding.toEquivRange`. |
| 65 | +When a better `α ≃ Set.range f` is known, use `Equiv.Perm.viaSetRange`. |
| 66 | +When `[Fintype α]` is not available, a noncomputable version is available as |
| 67 | +`Equiv.Perm.viaEmbedding`. |
| 68 | +-/ |
| 69 | +def Equiv.Perm.viaFintypeEmbedding : Equiv.Perm β := |
| 70 | + e.extendDomain f.toEquivRange |
| 71 | +#align equiv.perm.via_fintype_embedding Equiv.Perm.viaFintypeEmbedding |
| 72 | + |
| 73 | +@[simp] |
| 74 | +theorem Equiv.Perm.viaFintypeEmbedding_apply_image (a : α) : |
| 75 | + e.viaFintypeEmbedding f (f a) = f (e a) := by |
| 76 | + rw [Equiv.Perm.viaFintypeEmbedding] |
| 77 | + convert Equiv.Perm.extendDomain_apply_image e (Function.Embedding.toEquivRange f) a |
| 78 | +#align equiv.perm.via_fintype_embedding_apply_image Equiv.Perm.viaFintypeEmbedding_apply_image |
| 79 | + |
| 80 | +theorem Equiv.Perm.viaFintypeEmbedding_apply_mem_range {b : β} (h : b ∈ Set.range f) : |
| 81 | + e.viaFintypeEmbedding f b = f (e (f.invOfMemRange ⟨b, h⟩)) := by |
| 82 | + simp only [viaFintypeEmbedding, Function.Embedding.invOfMemRange] |
| 83 | + rw [Equiv.Perm.extendDomain_apply_subtype] |
| 84 | + congr |
| 85 | +#align equiv.perm.via_fintype_embedding_apply_mem_range Equiv.Perm.viaFintypeEmbedding_apply_mem_range |
| 86 | + |
| 87 | +theorem Equiv.Perm.viaFintypeEmbedding_apply_not_mem_range {b : β} (h : b ∉ Set.range f) : |
| 88 | + e.viaFintypeEmbedding f b = b := by |
| 89 | + rwa [Equiv.Perm.viaFintypeEmbedding, Equiv.Perm.extendDomain_apply_not_subtype] |
| 90 | +#align equiv.perm.via_fintype_embedding_apply_not_mem_range Equiv.Perm.viaFintypeEmbedding_apply_not_mem_range |
| 91 | + |
| 92 | +@[simp] |
| 93 | +theorem Equiv.Perm.viaFintypeEmbedding_sign [DecidableEq α] [Fintype β] : |
| 94 | + Equiv.Perm.sign (e.viaFintypeEmbedding f) = Equiv.Perm.sign e := by |
| 95 | + simp [Equiv.Perm.viaFintypeEmbedding] |
| 96 | +#align equiv.perm.via_fintype_embedding_sign Equiv.Perm.viaFintypeEmbedding_sign |
| 97 | + |
| 98 | +namespace Equiv |
| 99 | + |
| 100 | +variable {p q : α → Prop} [DecidablePred p] [DecidablePred q] |
| 101 | + |
| 102 | +/-- If `e` is an equivalence between two subtypes of a fintype `α`, `e.toCompl` |
| 103 | +is an equivalence between the complement of those subtypes. |
| 104 | +
|
| 105 | +See also `Equiv.compl`, for a computable version when a term of type |
| 106 | +`{e' : α ≃ α // ∀ x : {x // p x}, e' x = e x}` is known. -/ |
| 107 | +noncomputable def toCompl (e : { x // p x } ≃ { x // q x }) : { x // ¬p x } ≃ { x // ¬q x } := |
| 108 | + Classical.choice |
| 109 | + (Fintype.card_eq.mp (Fintype.card_compl_eq_card_compl _ _ (Fintype.card_congr e))) |
| 110 | +#align equiv.to_compl Equiv.toCompl |
| 111 | + |
| 112 | +/-- If `e` is an equivalence between two subtypes of a fintype `α`, `e.extendSubtype` |
| 113 | +is a permutation of `α` acting like `e` on the subtypes and doing something arbitrary outside. |
| 114 | +
|
| 115 | +Note that when `p = q`, `Equiv.Perm.subtypeCongr e (Equiv.refl _)` can be used instead. -/ |
| 116 | +noncomputable abbrev extendSubtype (e : { x // p x } ≃ { x // q x }) : Perm α := |
| 117 | + subtypeCongr e e.toCompl |
| 118 | +#align equiv.extend_subtype Equiv.extendSubtype |
| 119 | + |
| 120 | +theorem extendSubtype_apply_of_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) : |
| 121 | + e.extendSubtype x = e ⟨x, hx⟩ := by |
| 122 | + dsimp only [extendSubtype] |
| 123 | + simp only [subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply] |
| 124 | + rw [sumCompl_apply_symm_of_pos _ _ hx, Sum.map_inl, sumCompl_apply_inl] |
| 125 | +#align equiv.extend_subtype_apply_of_mem Equiv.extendSubtype_apply_of_mem |
| 126 | + |
| 127 | +theorem extendSubtype_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : p x) : |
| 128 | + q (e.extendSubtype x) := by |
| 129 | + convert (e ⟨x, hx⟩).2 |
| 130 | + rw [e.extendSubtype_apply_of_mem _ hx] |
| 131 | +#align equiv.extend_subtype_mem Equiv.extendSubtype_mem |
| 132 | + |
| 133 | +theorem extendSubtype_apply_of_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) : |
| 134 | + e.extendSubtype x = e.toCompl ⟨x, hx⟩ := by |
| 135 | + dsimp only [extendSubtype] |
| 136 | + simp only [subtypeCongr, Equiv.trans_apply, Equiv.sumCongr_apply] |
| 137 | + rw [sumCompl_apply_symm_of_neg _ _ hx, Sum.map_inr, sumCompl_apply_inr] |
| 138 | +#align equiv.extend_subtype_apply_of_not_mem Equiv.extendSubtype_apply_of_not_mem |
| 139 | + |
| 140 | +theorem extendSubtype_not_mem (e : { x // p x } ≃ { x // q x }) (x) (hx : ¬p x) : |
| 141 | + ¬q (e.extendSubtype x) := by |
| 142 | + convert (e.toCompl ⟨x, hx⟩).2 |
| 143 | + rw [e.extendSubtype_apply_of_not_mem _ hx] |
| 144 | +#align equiv.extend_subtype_not_mem Equiv.extendSubtype_not_mem |
| 145 | + |
| 146 | +end Equiv |
0 commit comments