Skip to content
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
wants to merge 21 commits into from

Conversation

Vierkantor
Copy link
Collaborator

@Vierkantor Vierkantor commented Jan 31, 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:

@[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:

Subclassing set_like

Contrary to mathlib's typical subclass pattern, we don't extend set_like, but take a set_like instance parameter:

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:

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). 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 MX s (where s : S) a lower prority than Y sX s so that subY_class S MY sX s is preferred over subY_class S MsubX_class S MX 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.


Open in Gitpod

@Vierkantor Vierkantor added awaiting-CI The author would like to see what CI has to say before doing more work. awaiting-review The author would like community review of the PR labels Jan 31, 2022
@YaelDillies
Copy link
Collaborator

This looks great!

@leanprover-community-bot-assistant leanprover-community-bot-assistant added blocked-by-other-PR This PR depends on another PR which is still in the queue. A bot manages this label via PR comment. merge-conflict Please `git merge origin/master` then a bot will remove this label. and removed blocked-by-other-PR This PR depends on another PR which is still in the queue. A bot manages this label via PR comment. labels Feb 2, 2022
@leanprover-community-bot-assistant leanprover-community-bot-assistant removed the merge-conflict Please `git merge origin/master` then a bot will remove this label. label Feb 10, 2022
@leanprover-community-bot-assistant leanprover-community-bot-assistant added the blocked-by-other-PR This PR depends on another PR which is still in the queue. A bot manages this label via PR comment. label 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.
@leanprover-community-bot-assistant leanprover-community-bot-assistant removed the blocked-by-other-PR This PR depends on another PR which is still in the queue. A bot manages this label via PR comment. label Feb 24, 2022
@leanprover-community-bot-assistant leanprover-community-bot-assistant added the merge-conflict Please `git merge origin/master` then a bot will remove this label. label Feb 24, 2022
@leanprover-community-bot-assistant leanprover-community-bot-assistant added merge-conflict Please `git merge origin/master` then a bot will remove this label. and removed merge-conflict Please `git merge origin/master` then a bot will remove this label. labels Feb 24, 2022
@leanprover-community-bot-assistant leanprover-community-bot-assistant removed the merge-conflict Please `git merge origin/master` then a bot will remove this label. label Mar 2, 2022
@eric-wieser
Copy link
Member

  • affine.simplex.orthogonal_projection_span is the new way to write orthogonal_projection (affine_span ℝ (set.range s.points)). Moving this into its own definition fixed a long string of timeouts (partially by splitting a slow declaration into two that are only half as slow, partially by guiding the elaborator a bit).

This no longer is part of this PR, right?

@leanprover-community-bot-assistant leanprover-community-bot-assistant removed the merge-conflict Please `git merge origin/master` then a bot will remove this label. label Apr 4, 2022
@riccardobrasca
Copy link
Member

bors d+

@bors
Copy link

bors bot commented Apr 5, 2022

✌️ Vierkantor can now approve this pull request. To approve and merge a pull request, simply reply with bors r+. More detailed instructions are available here.

@github-actions github-actions bot added delegated The PR author may merge after reviewing final suggestions. and removed awaiting-review The author would like community review of the PR labels Apr 5, 2022
@Vierkantor
Copy link
Collaborator Author

Everything also builds on my machine, so:

bors r+

@github-actions github-actions bot added the ready-to-merge All that is left is for bors to build and merge this PR. (Remember you need to say `bors r+`.) label Apr 5, 2022
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>
@bors
Copy link

bors bot commented Apr 5, 2022

Pull request successfully merged into master.

Build succeeded:

@bors bors bot changed the title feat(*): define subobject classes from submonoid up to subfield [Merged by Bors] - feat(*): define subobject classes from submonoid up to subfield Apr 5, 2022
@bors bors bot closed this Apr 5, 2022
@bors bors bot deleted the submonoid_class-def branch April 5, 2022 14:51
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+`.)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants