-
Notifications
You must be signed in to change notification settings - Fork 297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Merged by Bors] - feat(*): define subobject classes from submonoid up to subfield #11750
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This looks great! |
3 tasks
This was referenced Feb 1, 2022
e4fc97b
to
bfa7d3a
Compare
eric-wieser
reviewed
Feb 1, 2022
eric-wieser
reviewed
Feb 1, 2022
8649a2a
to
e9d0a2d
Compare
eric-wieser
reviewed
Feb 22, 2022
eric-wieser
reviewed
Feb 22, 2022
eric-wieser
reviewed
Feb 22, 2022
bors bot
pushed a commit
that referenced
this pull request
Feb 24, 2022
This PR is part of the subobject refactor #11545, fixing a timeout caused by some expensive defeq checks. I introduce a new definition `simplex.orthogonal_projection_span s := orthogonal_projection (affine_span ℝ (set.range s.points))`, and extract a couple of its properties from (repetitive) parts of proofs in `circumcenter.lean`, especially `eq_or_eq_reflection_of_dist_eq`. This makes the latter proof noticeably faster, especially after commit #11750.
This PR/issue depends on: |
1393075
to
a7d7506
Compare
a7d7506
to
d714b21
Compare
This no longer is part of this PR, right? |
Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
The other ones already had this form.
…ut `add_subgroup_class`
…_space` just barely goes past it
b8327e5
to
fbbf8a2
Compare
bors d+ |
✌️ Vierkantor can now approve this pull request. To approve and merge a pull request, simply reply with |
Everything also builds on my machine, so: bors r+ |
bors bot
pushed a commit
that referenced
this pull request
Apr 5, 2022
The next part of my big refactoring plans: subobject classes in the same style as morphism classes. This PR introduces the following subclasses of `set_like`: * `one_mem_class`, `zero_mem_class`, `mul_mem_class`, `add_mem_class`, `inv_mem_class`, `neg_mem_class` * `submonoid_class`, `add_submonoid_class` * `subgroup_class`, `add_subgroup_class` * `subsemiring_class`, `subring_class`, `subfield_class` The main purpose of this refactor is that we can replace the wide variety of lemmas like `{add_submonoid,add_subgroup,subring,subfield,submodule,subwhatever}.{prod,sum}_mem` with a single `prod_mem` lemma that is generic over all types `B` that extend `submonoid`: ```lean @[to_additive] lemma prod_mem {M : Type*} [comm_monoid M] [set_like B M] [submonoid_class B M] {ι : Type*} {t : finset ι} {f : ι → M} (h : ∀c ∈ t, f c ∈ S) : ∏ c in t, f c ∈ S ``` ## API changes * When you extend a `struct subobject`, make sure to create a corresponding `subobject_class` instance. ## Upcoming PRs This PR splits out the first part of #11545, namely defining the subobject classes. I am planning these follow-up PRs for further parts of #11545: - [ ] make the subobject consistently implicit in `{add,mul}_mem` #11758 - [ ] remove duplicate instances like `subgroup.to_group` (replaced by the `subgroup_class.to_subgroup` instances that are added by this PR) #11759 - [ ] further deduplication such as `finsupp_sum_mem` ## Subclassing `set_like` Contrary to mathlib's typical subclass pattern, we don't extend `set_like`, but take a `set_like` instance parameter: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] [set_like S M] := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` instead of: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] extends set_like S M := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` The main reason is that this avoids some big defeq checks when typechecking e.g. `x * y : s`, where `s : S` and `[comm_group G] [subgroup_class S G]`. Namely, the type `coe_sort s` could be given by `subgroup_class → @@submonoid_class _ _ (comm_group.to_group.to_monoid) → set_like → has_coe_to_sort` or by `subgroup_class → @@submonoid_class _ _ (comm_group.to_comm_monoid.to_monoid) → set_like → has_coe_to_sort`. When checking that `has_mul` on the first type is the same as `has_mul` on the second type, those two inheritance paths are unified many times over ([sometimes exponentially many](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Why.20is.20.60int.2Ecast_abs.60.20so.20slow.3F/near/266945077)). So it's important to keep the size of types small, and therefore we avoid `extends`-based inheritance. ## Defeq fixes Adding instances like `subgroup_class.to_group` means that there are now two (defeq) group instances for `subgroup`. This makes some code more fragile, until we can replace `subgroup.to_group` with its more generic form in a follow-up PR. Especially when taking subgroups of subgroups I needed to help the elaborator in a few places. These should be minimally invasive for other uses of the code. ## Timeout fixes Some of the leaf files started timing out, so I made a couple of fixes. Generally these can be classed as: * `squeeze_simps` * Give inheritance `subX_class S M` → `X s` (where `s : S`) a lower prority than `Y s` → `X s` so that `subY_class S M` → `Y s` → `X s` is preferred over `subY_class S M` → `subX_class S M` → `X s`. This addresses slow unifications when `x : s`, `s` is a submonoid of `t`, which is itself a subgroup of `G`: existing code expects to go `subgroup → group → monoid`, which got changed to `subgroup_class → submonoid_class → monoid`; when this kind of unification issue appears in your type this results in slow unification. By tweaking the priorities, we help the elaborator find our preferred instance, avoiding the big defeq checks. (The real fix should of course be to fix the unifier so it doesn't become exponential in these kinds of cases.) * Split a long proof with duplication into smaller parts. This was basically my last resort. I decided to bump the limit for the `fails_quickly` linter for `measure_theory.Lp_meas.complete_space`, which apparently just barely goes over this limit now. The time difference was about 10%-20% for that specific instance. Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com> Co-authored-by: Riccardo Brasca <riccardo.brasca@gmail.com>
Pull request successfully merged into master. Build succeeded: |
jjaassoonn
pushed a commit
that referenced
this pull request
Apr 7, 2022
The next part of my big refactoring plans: subobject classes in the same style as morphism classes. This PR introduces the following subclasses of `set_like`: * `one_mem_class`, `zero_mem_class`, `mul_mem_class`, `add_mem_class`, `inv_mem_class`, `neg_mem_class` * `submonoid_class`, `add_submonoid_class` * `subgroup_class`, `add_subgroup_class` * `subsemiring_class`, `subring_class`, `subfield_class` The main purpose of this refactor is that we can replace the wide variety of lemmas like `{add_submonoid,add_subgroup,subring,subfield,submodule,subwhatever}.{prod,sum}_mem` with a single `prod_mem` lemma that is generic over all types `B` that extend `submonoid`: ```lean @[to_additive] lemma prod_mem {M : Type*} [comm_monoid M] [set_like B M] [submonoid_class B M] {ι : Type*} {t : finset ι} {f : ι → M} (h : ∀c ∈ t, f c ∈ S) : ∏ c in t, f c ∈ S ``` ## API changes * When you extend a `struct subobject`, make sure to create a corresponding `subobject_class` instance. ## Upcoming PRs This PR splits out the first part of #11545, namely defining the subobject classes. I am planning these follow-up PRs for further parts of #11545: - [ ] make the subobject consistently implicit in `{add,mul}_mem` #11758 - [ ] remove duplicate instances like `subgroup.to_group` (replaced by the `subgroup_class.to_subgroup` instances that are added by this PR) #11759 - [ ] further deduplication such as `finsupp_sum_mem` ## Subclassing `set_like` Contrary to mathlib's typical subclass pattern, we don't extend `set_like`, but take a `set_like` instance parameter: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] [set_like S M] := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` instead of: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] extends set_like S M := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` The main reason is that this avoids some big defeq checks when typechecking e.g. `x * y : s`, where `s : S` and `[comm_group G] [subgroup_class S G]`. Namely, the type `coe_sort s` could be given by `subgroup_class → @@submonoid_class _ _ (comm_group.to_group.to_monoid) → set_like → has_coe_to_sort` or by `subgroup_class → @@submonoid_class _ _ (comm_group.to_comm_monoid.to_monoid) → set_like → has_coe_to_sort`. When checking that `has_mul` on the first type is the same as `has_mul` on the second type, those two inheritance paths are unified many times over ([sometimes exponentially many](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Why.20is.20.60int.2Ecast_abs.60.20so.20slow.3F/near/266945077)). So it's important to keep the size of types small, and therefore we avoid `extends`-based inheritance. ## Defeq fixes Adding instances like `subgroup_class.to_group` means that there are now two (defeq) group instances for `subgroup`. This makes some code more fragile, until we can replace `subgroup.to_group` with its more generic form in a follow-up PR. Especially when taking subgroups of subgroups I needed to help the elaborator in a few places. These should be minimally invasive for other uses of the code. ## Timeout fixes Some of the leaf files started timing out, so I made a couple of fixes. Generally these can be classed as: * `squeeze_simps` * Give inheritance `subX_class S M` → `X s` (where `s : S`) a lower prority than `Y s` → `X s` so that `subY_class S M` → `Y s` → `X s` is preferred over `subY_class S M` → `subX_class S M` → `X s`. This addresses slow unifications when `x : s`, `s` is a submonoid of `t`, which is itself a subgroup of `G`: existing code expects to go `subgroup → group → monoid`, which got changed to `subgroup_class → submonoid_class → monoid`; when this kind of unification issue appears in your type this results in slow unification. By tweaking the priorities, we help the elaborator find our preferred instance, avoiding the big defeq checks. (The real fix should of course be to fix the unifier so it doesn't become exponential in these kinds of cases.) * Split a long proof with duplication into smaller parts. This was basically my last resort. I decided to bump the limit for the `fails_quickly` linter for `measure_theory.Lp_meas.complete_space`, which apparently just barely goes over this limit now. The time difference was about 10%-20% for that specific instance. Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com> Co-authored-by: Riccardo Brasca <riccardo.brasca@gmail.com>
jjaassoonn
pushed a commit
that referenced
this pull request
Apr 7, 2022
The next part of my big refactoring plans: subobject classes in the same style as morphism classes. This PR introduces the following subclasses of `set_like`: * `one_mem_class`, `zero_mem_class`, `mul_mem_class`, `add_mem_class`, `inv_mem_class`, `neg_mem_class` * `submonoid_class`, `add_submonoid_class` * `subgroup_class`, `add_subgroup_class` * `subsemiring_class`, `subring_class`, `subfield_class` The main purpose of this refactor is that we can replace the wide variety of lemmas like `{add_submonoid,add_subgroup,subring,subfield,submodule,subwhatever}.{prod,sum}_mem` with a single `prod_mem` lemma that is generic over all types `B` that extend `submonoid`: ```lean @[to_additive] lemma prod_mem {M : Type*} [comm_monoid M] [set_like B M] [submonoid_class B M] {ι : Type*} {t : finset ι} {f : ι → M} (h : ∀c ∈ t, f c ∈ S) : ∏ c in t, f c ∈ S ``` ## API changes * When you extend a `struct subobject`, make sure to create a corresponding `subobject_class` instance. ## Upcoming PRs This PR splits out the first part of #11545, namely defining the subobject classes. I am planning these follow-up PRs for further parts of #11545: - [ ] make the subobject consistently implicit in `{add,mul}_mem` #11758 - [ ] remove duplicate instances like `subgroup.to_group` (replaced by the `subgroup_class.to_subgroup` instances that are added by this PR) #11759 - [ ] further deduplication such as `finsupp_sum_mem` ## Subclassing `set_like` Contrary to mathlib's typical subclass pattern, we don't extend `set_like`, but take a `set_like` instance parameter: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] [set_like S M] := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` instead of: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] extends set_like S M := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` The main reason is that this avoids some big defeq checks when typechecking e.g. `x * y : s`, where `s : S` and `[comm_group G] [subgroup_class S G]`. Namely, the type `coe_sort s` could be given by `subgroup_class → @@submonoid_class _ _ (comm_group.to_group.to_monoid) → set_like → has_coe_to_sort` or by `subgroup_class → @@submonoid_class _ _ (comm_group.to_comm_monoid.to_monoid) → set_like → has_coe_to_sort`. When checking that `has_mul` on the first type is the same as `has_mul` on the second type, those two inheritance paths are unified many times over ([sometimes exponentially many](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Why.20is.20.60int.2Ecast_abs.60.20so.20slow.3F/near/266945077)). So it's important to keep the size of types small, and therefore we avoid `extends`-based inheritance. ## Defeq fixes Adding instances like `subgroup_class.to_group` means that there are now two (defeq) group instances for `subgroup`. This makes some code more fragile, until we can replace `subgroup.to_group` with its more generic form in a follow-up PR. Especially when taking subgroups of subgroups I needed to help the elaborator in a few places. These should be minimally invasive for other uses of the code. ## Timeout fixes Some of the leaf files started timing out, so I made a couple of fixes. Generally these can be classed as: * `squeeze_simps` * Give inheritance `subX_class S M` → `X s` (where `s : S`) a lower prority than `Y s` → `X s` so that `subY_class S M` → `Y s` → `X s` is preferred over `subY_class S M` → `subX_class S M` → `X s`. This addresses slow unifications when `x : s`, `s` is a submonoid of `t`, which is itself a subgroup of `G`: existing code expects to go `subgroup → group → monoid`, which got changed to `subgroup_class → submonoid_class → monoid`; when this kind of unification issue appears in your type this results in slow unification. By tweaking the priorities, we help the elaborator find our preferred instance, avoiding the big defeq checks. (The real fix should of course be to fix the unifier so it doesn't become exponential in these kinds of cases.) * Split a long proof with duplication into smaller parts. This was basically my last resort. I decided to bump the limit for the `fails_quickly` linter for `measure_theory.Lp_meas.complete_space`, which apparently just barely goes over this limit now. The time difference was about 10%-20% for that specific instance. Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com> Co-authored-by: Riccardo Brasca <riccardo.brasca@gmail.com>
jjaassoonn
pushed a commit
that referenced
this pull request
Apr 7, 2022
The next part of my big refactoring plans: subobject classes in the same style as morphism classes. This PR introduces the following subclasses of `set_like`: * `one_mem_class`, `zero_mem_class`, `mul_mem_class`, `add_mem_class`, `inv_mem_class`, `neg_mem_class` * `submonoid_class`, `add_submonoid_class` * `subgroup_class`, `add_subgroup_class` * `subsemiring_class`, `subring_class`, `subfield_class` The main purpose of this refactor is that we can replace the wide variety of lemmas like `{add_submonoid,add_subgroup,subring,subfield,submodule,subwhatever}.{prod,sum}_mem` with a single `prod_mem` lemma that is generic over all types `B` that extend `submonoid`: ```lean @[to_additive] lemma prod_mem {M : Type*} [comm_monoid M] [set_like B M] [submonoid_class B M] {ι : Type*} {t : finset ι} {f : ι → M} (h : ∀c ∈ t, f c ∈ S) : ∏ c in t, f c ∈ S ``` ## API changes * When you extend a `struct subobject`, make sure to create a corresponding `subobject_class` instance. ## Upcoming PRs This PR splits out the first part of #11545, namely defining the subobject classes. I am planning these follow-up PRs for further parts of #11545: - [ ] make the subobject consistently implicit in `{add,mul}_mem` #11758 - [ ] remove duplicate instances like `subgroup.to_group` (replaced by the `subgroup_class.to_subgroup` instances that are added by this PR) #11759 - [ ] further deduplication such as `finsupp_sum_mem` ## Subclassing `set_like` Contrary to mathlib's typical subclass pattern, we don't extend `set_like`, but take a `set_like` instance parameter: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] [set_like S M] := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` instead of: ```lean class one_mem_class (S : Type*) (M : out_param $ Type*) [has_one M] extends set_like S M := (one_mem : ∀ (s : S), (1 : M) ∈ s) ``` The main reason is that this avoids some big defeq checks when typechecking e.g. `x * y : s`, where `s : S` and `[comm_group G] [subgroup_class S G]`. Namely, the type `coe_sort s` could be given by `subgroup_class → @@submonoid_class _ _ (comm_group.to_group.to_monoid) → set_like → has_coe_to_sort` or by `subgroup_class → @@submonoid_class _ _ (comm_group.to_comm_monoid.to_monoid) → set_like → has_coe_to_sort`. When checking that `has_mul` on the first type is the same as `has_mul` on the second type, those two inheritance paths are unified many times over ([sometimes exponentially many](https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Why.20is.20.60int.2Ecast_abs.60.20so.20slow.3F/near/266945077)). So it's important to keep the size of types small, and therefore we avoid `extends`-based inheritance. ## Defeq fixes Adding instances like `subgroup_class.to_group` means that there are now two (defeq) group instances for `subgroup`. This makes some code more fragile, until we can replace `subgroup.to_group` with its more generic form in a follow-up PR. Especially when taking subgroups of subgroups I needed to help the elaborator in a few places. These should be minimally invasive for other uses of the code. ## Timeout fixes Some of the leaf files started timing out, so I made a couple of fixes. Generally these can be classed as: * `squeeze_simps` * Give inheritance `subX_class S M` → `X s` (where `s : S`) a lower prority than `Y s` → `X s` so that `subY_class S M` → `Y s` → `X s` is preferred over `subY_class S M` → `subX_class S M` → `X s`. This addresses slow unifications when `x : s`, `s` is a submonoid of `t`, which is itself a subgroup of `G`: existing code expects to go `subgroup → group → monoid`, which got changed to `subgroup_class → submonoid_class → monoid`; when this kind of unification issue appears in your type this results in slow unification. By tweaking the priorities, we help the elaborator find our preferred instance, avoiding the big defeq checks. (The real fix should of course be to fix the unifier so it doesn't become exponential in these kinds of cases.) * Split a long proof with duplication into smaller parts. This was basically my last resort. I decided to bump the limit for the `fails_quickly` linter for `measure_theory.Lp_meas.complete_space`, which apparently just barely goes over this limit now. The time difference was about 10%-20% for that specific instance. Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com> Co-authored-by: Riccardo Brasca <riccardo.brasca@gmail.com>
bors bot
pushed a commit
that referenced
this pull request
Apr 9, 2022
This subobject class refactor PR follows up from #11750 by moving the `{zero,one,add,mul,...}_mem_class` lemmas to the root namespace and marking the previous `sub{monoid,group,module,algebra,...}.{zero,one,add,mul,...}_mem` lemmas as `protected`. This is the second part of #11545 to be split off. I made the subobject parameter to the `_mem` lemmas implicit if it appears in the hypotheses, e.g. ```lean lemma mul_mem {S M : Type*} [monoid M] [set_like S M] [submonoid_class S M] {s : S} {x y : M} (hx : x ∈ s) (hy : y ∈ s) : x * y ∈ s ``` instead of having `(s : S)` explicit. The generic `_mem` lemmas are not namespaced, so there is no dot notation that requires `s` to be explicit. Also there were already a couple of instances for the same operator where `s` was implicit and others where `s` was explicit, so some change was needed.
bors bot
pushed a commit
that referenced
this pull request
Apr 9, 2022
This subobject class refactor PR follows up from #11750 by moving the `{zero,one,add,mul,...}_mem_class` lemmas to the root namespace and marking the previous `sub{monoid,group,module,algebra,...}.{zero,one,add,mul,...}_mem` lemmas as `protected`. This is the second part of #11545 to be split off. I made the subobject parameter to the `_mem` lemmas implicit if it appears in the hypotheses, e.g. ```lean lemma mul_mem {S M : Type*} [monoid M] [set_like S M] [submonoid_class S M] {s : S} {x y : M} (hx : x ∈ s) (hy : y ∈ s) : x * y ∈ s ``` instead of having `(s : S)` explicit. The generic `_mem` lemmas are not namespaced, so there is no dot notation that requires `s` to be explicit. Also there were already a couple of instances for the same operator where `s` was implicit and others where `s` was explicit, so some change was needed.
bors bot
pushed a commit
that referenced
this pull request
Apr 9, 2022
This subobject class refactor PR follows up from #11750 by moving the `{zero,one,add,mul,...}_mem_class` lemmas to the root namespace and marking the previous `sub{monoid,group,module,algebra,...}.{zero,one,add,mul,...}_mem` lemmas as `protected`. This is the second part of #11545 to be split off. I made the subobject parameter to the `_mem` lemmas implicit if it appears in the hypotheses, e.g. ```lean lemma mul_mem {S M : Type*} [monoid M] [set_like S M] [submonoid_class S M] {s : S} {x y : M} (hx : x ∈ s) (hy : y ∈ s) : x * y ∈ s ``` instead of having `(s : S)` explicit. The generic `_mem` lemmas are not namespaced, so there is no dot notation that requires `s` to be explicit. Also there were already a couple of instances for the same operator where `s` was implicit and others where `s` was explicit, so some change was needed.
bors bot
pushed a commit
that referenced
this pull request
Apr 10, 2022
This subobject class refactor PR follows up from #11750 by moving the `{zero,one,add,mul,...}_mem_class` lemmas to the root namespace and marking the previous `sub{monoid,group,module,algebra,...}.{zero,one,add,mul,...}_mem` lemmas as `protected`. This is the second part of #11545 to be split off. I made the subobject parameter to the `_mem` lemmas implicit if it appears in the hypotheses, e.g. ```lean lemma mul_mem {S M : Type*} [monoid M] [set_like S M] [submonoid_class S M] {s : S} {x y : M} (hx : x ∈ s) (hy : y ∈ s) : x * y ∈ s ``` instead of having `(s : S)` explicit. The generic `_mem` lemmas are not namespaced, so there is no dot notation that requires `s` to be explicit. Also there were already a couple of instances for the same operator where `s` was implicit and others where `s` was explicit, so some change was needed.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
delegated
The PR author may merge after reviewing final suggestions.
ready-to-merge
All that is left is for bors to build and merge this PR. (Remember you need to say `bors r+`.)
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The next part of my big refactoring plans: subobject classes in the same style as morphism classes.
This PR introduces the following subclasses of
set_like
:one_mem_class
,zero_mem_class
,mul_mem_class
,add_mem_class
,inv_mem_class
,neg_mem_class
submonoid_class
,add_submonoid_class
subgroup_class
,add_subgroup_class
subsemiring_class
,subring_class
,subfield_class
The main purpose of this refactor is that we can replace the wide variety of lemmas like
{add_submonoid,add_subgroup,subring,subfield,submodule,subwhatever}.{prod,sum}_mem
with a singleprod_mem
lemma that is generic over all typesB
that extendsubmonoid
:API changes
struct subobject
, make sure to create a correspondingsubobject_class
instance.Upcoming PRs
This PR splits out the first part of #11545, namely defining the subobject classes. I am planning these follow-up PRs for further parts of #11545:
{add,mul}_mem
[Merged by Bors] - feat(group_theory): use genericsubobject_class
lemmas #11758subgroup.to_group
(replaced by thesubgroup_class.to_subgroup
instances that are added by this PR) refactor(*): remove duplicate subobject instances #11759finsupp_sum_mem
Subclassing
set_like
Contrary to mathlib's typical subclass pattern, we don't extend
set_like
, but take aset_like
instance parameter:instead of:
The main reason is that this avoids some big defeq checks when typechecking e.g.
x * y : s
, wheres : S
and[comm_group G] [subgroup_class S G]
. Namely, the typecoe_sort s
could be given bysubgroup_class → @@submonoid_class _ _ (comm_group.to_group.to_monoid) → set_like → has_coe_to_sort
or bysubgroup_class → @@submonoid_class _ _ (comm_group.to_comm_monoid.to_monoid) → set_like → has_coe_to_sort
. When checking thathas_mul
on the first type is the same ashas_mul
on the second type, those two inheritance paths are unified many times over (sometimes exponentially many). So it's important to keep the size of types small, and therefore we avoidextends
-based inheritance.Defeq fixes
Adding instances like
subgroup_class.to_group
means that there are now two (defeq) group instances forsubgroup
. This makes some code more fragile, until we can replacesubgroup.to_group
with its more generic form in a follow-up PR. Especially when taking subgroups of subgroups I needed to help the elaborator in a few places. These should be minimally invasive for other uses of the code.Timeout fixes
Some of the leaf files started timing out, so I made a couple of fixes. Generally these can be classed as:
squeeze_simps
subX_class S M
→X s
(wheres : S
) a lower prority thanY s
→X s
so thatsubY_class S M
→Y s
→X s
is preferred oversubY_class S M
→subX_class S M
→X s
. This addresses slow unifications whenx : s
,s
is a submonoid oft
, which is itself a subgroup ofG
: existing code expects to gosubgroup → group → monoid
, which got changed tosubgroup_class → submonoid_class → monoid
; when this kind of unification issue appears in your type this results in slow unification. By tweaking the priorities, we help the elaborator find our preferred instance, avoiding the big defeq checks. (The real fix should of course be to fix the unifier so it doesn't become exponential in these kinds of cases.)I decided to bump the limit for the
fails_quickly
linter formeasure_theory.Lp_meas.complete_space
, which apparently just barely goes over this limit now. The time difference was about 10%-20% for that specific instance.algebraic_iff_integral
#11773