Zulip Chat Archive
Stream: general
Topic: Maximum Class-Instance Resolution Depth Reached
Ken Lee (Jul 27 2019 at 07:51):
This appeared when I tried to use quotient.mk. What does this mean and how can I fix this?
Scott Morrison (Jul 27 2019 at 08:11):
Sometimes it just means you need to increase the bound. Other times it means that something has gone haywire, and instances have been defined that cause the class resolution mechanism (which isn't very clever) to enter a loop.
Johan Commelin (Jul 27 2019 at 08:12):
@Ken Lee In what context where you using quotients?
Scott Morrison (Jul 27 2019 at 08:12):
Try set_option class.instance_max_depth 50
.
Johan Commelin (Jul 27 2019 at 08:12):
A bunch of algebra? Or a simple equivalence relation?
Ken Lee (Jul 27 2019 at 08:13):
I was trying to define orbits under a group action.
Ken Lee (Jul 27 2019 at 08:15):
Try
set_option class.instance_max_depth 50
.
This hasn't worked
Johan Commelin (Jul 27 2019 at 08:15):
Try 100
Johan Commelin (Jul 27 2019 at 08:15):
If that fails, it means something else is wrong.
Johan Commelin (Jul 27 2019 at 08:16):
Also... orbits are already in mathlib. (Of course that doesn't forbid you from defining your own. But just so you know.)
Ken Lee (Jul 27 2019 at 08:16):
Try 100
I tried 500. It still doesn't work.
Johan Commelin (Jul 27 2019 at 08:16):
Ok, then we need more context to figure out what went wrong.
Chris Hughes (Jul 27 2019 at 08:17):
Did you make thesetoid
an instance?
Ken Lee (Jul 27 2019 at 08:17):
Also... orbits are already in mathlib. (Of course that doesn't forbid you from defining your own. But just so you know.)
I know haha was just seeing if I can define it in Lean
Ken Lee (Jul 27 2019 at 08:17):
Did you make the
setoid
an instance?
Yes @Chris Hughes
Ken Lee (Jul 27 2019 at 08:19):
Ok, then we need more context to figure out what went wrong.
Should I post the entire code? I haven't written much
Chris Hughes (Jul 27 2019 at 08:19):
Yes. It might be that the instance depends on an argument that can't be inferred by type class resolution.
Ken Lee (Jul 27 2019 at 08:24):
import algebra.group universes u0 u1 u2 open function #print setoid #print congr theorem congr_alt {X : Type u0} {Y : Type u1} {f₁ f₂ : X → Y} {x₁ x₂ : X} : x₁ = x₂ → f₁ = f₂ → f₁ x₁ = f₂ x₂ := λ x1_eq_x2 f1_eq_f2, congr f1_eq_f2 x1_eq_x2 structure action (G : Type u0) [group G] (X : Type u1) := (action : G → (X → X)) (map_one : action 1 = id) (map_mul : ∀ f g : G, action (f * g) = action f ∘ action g) infix ` action `:1000 := action instance action.setoid {G : Type u0} [group G] {X : Type u1} (GX : G action X) : setoid X := { r := λ x y : X, ∃ g : G, GX.action g x = y, iseqv := ⟨ -- Refl λ x : X, ⟨1, GX.map_one.symm ▸ rfl⟩, -- Symm λ (x y : X) ⟨g,gx_eq_y⟩, ⟨g⁻¹, calc GX.action g⁻¹ y = GX.action g⁻¹ (GX.action g x) : gx_eq_y.symm ▸ rfl ... = (GX.action g⁻¹ ∘ GX.action g) x : rfl ... = GX.action (g⁻¹ * g) x : congr_alt rfl $ (GX.map_mul _ _).symm ... = GX.action 1 x : congr_alt rfl $ inv_mul_self g ▸ rfl ... = x : GX.map_one.symm ▸ rfl ⟩ , -- Trans λ (x y z : X) ⟨g,gx_eq_y⟩ ⟨h, hy_eq_z⟩, ⟨h * g, calc GX.action (h * g) x = (GX.action h ∘ GX.action g) x : congr_alt rfl $ GX.map_mul _ _ ... = GX.action h y : gx_eq_y ▸ rfl ... = z : hy_eq_z ⟩ ⟩, } def orbits {G : Type u0} [group G] {X: Type u1} (GX : G action X) := quotient (action.setoid GX) set_option class.instance_max_depth 100 def orbit {G : Type u0} [group G] {X: Type u1} (GX : G action X) (x : X) : orbits GX := ⟦x⟧
Ken Lee (Jul 27 2019 at 08:27):
Yes. It might be that the instance depends on an argument that can't be inferred by type class resolution.
May I ask, what is type class resolution?
Kenny Lau (Jul 27 2019 at 08:34):
def orbit {G : Type u0} [group G] {X: Type u1} (GX : G action X) (x : X) : orbits GX := quotient.mk' x
works fine
Chris Hughes (Jul 27 2019 at 08:34):
It's the process that fill in the arguments in square brackets.
Kenny Lau (Jul 27 2019 at 08:36):
oh don't forget to import data.quot
Chris Hughes (Jul 27 2019 at 08:38):
So the problem was that type class inference didn't know which group action you meant. This information can however be inferred from the expected type (which type class resolution doesn't use). quotient.mk'
puts the setoid argument in {}
brackets instead of []
brackets, so it uses a different procedure to infer the argument, which does use the expected type.
Kenny Lau (Jul 27 2019 at 08:38):
btw have you looked at the file group_theory.group_action
?
Kenny Lau (Jul 27 2019 at 08:39):
(deleted)
Ken Lee (Jul 27 2019 at 08:41):
So the problem was that type class inference didn't know which group action you meant. This information can however be inferred from the expected type (which type class resolution doesn't use).
quotient.mk'
puts the setoid argument in{}
brackets instead of[]
brackets, so it uses a different procedure to infer the argument, which does use the expected type.
Aha thanks for the explanation
Ken Lee (Jul 27 2019 at 08:42):
btw have you looked at the file
group_theory.group_action
?
No i have not. Why do you ask? @Kenny Lau
Kenny Lau (Jul 27 2019 at 08:43):
because group action is already defined there
Ken Lee (Jul 27 2019 at 08:45):
because group action is already defined there
Yes I know. But I wanted to exercise my Lean skills!
Kenny Lau (Jul 27 2019 at 08:47):
ok so a difference is that in the official file, the group action is a class
Kenny Lau (Jul 27 2019 at 08:47):
while you made it a structure
Ken Lee (Jul 27 2019 at 08:50):
I forget the difference between the two. Should I have defined it as a class instead? (if so, why?)
Kenny Lau (Jul 27 2019 at 08:51):
I put your file in a washing machine
Kenny Lau (Jul 27 2019 at 08:51):
import algebra.group universes u0 u1 u2 class has_scalar (G : Type u0) (X : Type u1) := (smul : G → X → X) infixr ` • `:73 := has_scalar.smul class action (G : Type u0) [group G] (X : Type u1) extends has_scalar G X := (one_smul : ∀ x : X, (1 : G) • x = x) (mul_smul : ∀ f g : G, ∀ x : X, (f * g) • x = f • (g • x)) export action (one_smul mul_smul) infix ` action `:1000 := action instance action.setoid (G : Type u0) [group G] (X : Type u1) [G action X] : setoid X := { r := λ x y : X, ∃ g : G, g • x = y, iseqv := ⟨ -- Refl λ x : X, ⟨1, by rw one_smul⟩, -- Symm λ (x y : X) ⟨g, gx_eq_y⟩, ⟨g⁻¹, by rw [← gx_eq_y, ← mul_smul, inv_mul_self, one_smul]⟩, -- Trans λ (x y z : X) ⟨g,gx_eq_y⟩ ⟨h, hy_eq_z⟩, ⟨h * g, by rw [mul_smul, gx_eq_y, hy_eq_z]⟩⟩ } def orbits (G : Type u0) [group G] (X: Type u1) [G action X] := quotient (action.setoid G X) def orbit (G : Type u0) [group G] (X: Type u1) [G action X] (x : X) : orbits G X := ⟦x⟧
Kenny Lau (Jul 27 2019 at 08:51):
@Chris Hughes should it be a class or a structure?
Kenny Lau (Jul 27 2019 at 08:52):
@Ken Lee was there a particular reason why you avoided rw
?
Ken Lee (Jul 27 2019 at 08:54):
Ah this is nice, so we can write g(x) = y
effectively.
Chris Hughes (Jul 27 2019 at 08:55):
But this is bad if you want a group to act on a set in lots of different ways.
Kenny Lau (Jul 27 2019 at 08:56):
yeah but then why does the official file use class
?
Chris Hughes (Jul 27 2019 at 08:57):
Because we haven't had that problem yet. I'm not sure of the best solution.
Chris Hughes (Jul 27 2019 at 08:57):
There is a mathlib issue about this.
Ken Lee (Jul 27 2019 at 08:58):
Doesn't structure
reflect better what we do in usual maths, "a group action is a tuple ..."? The actually action itself is important to keep, no?
Ken Lee (Jul 27 2019 at 08:58):
Ken Lee was there a particular reason why you avoided
rw
?
I dunno because I like term mode? @Kenny Lau
Ken Lee (Jul 27 2019 at 09:01):
I put your file in a washing machine
So in the shrunken version of my file, types can only have at most one action on them?
Chris Hughes (Jul 27 2019 at 09:02):
At most one action from the same group. Or at least it will be a pain to have multiple actions from the same group.
Johan Commelin (Jul 27 2019 at 09:19):
But we can use type wrappers to solve this problem.
Chris Hughes (Jul 27 2019 at 09:23):
I'm not sure this will always be a good solution. What if it's an action of the reals on the reals? There's a lot of stuff to transfer from reals onto wrapped reals. And then I can't do action1 x y + action2 x y
, because the wrappers will be different.
Kenny Lau (Jul 27 2019 at 09:24):
let's think about group cohomology @Johan Commelin
Kenny Lau (Jul 27 2019 at 09:24):
do we have two actions from the same group on the same module?
Johan Commelin (Jul 27 2019 at 09:25):
Not in the generic case, right?
Kenny Lau (Jul 27 2019 at 09:30):
I mean do we have examples of those
Johan Commelin (Jul 27 2019 at 09:32):
Probably yes, I can't immediately think of any.
Kevin Buzzard (Jul 27 2019 at 09:55):
Tate twists
Kenny Lau (Jul 27 2019 at 09:57):
According to Wiki the m-th Tate twist of V is V tensor Q_p(-1) m times
Johan Commelin (Jul 27 2019 at 10:22):
If we want examples of this, I think we shouldn't look so far away. For any group (typically non-abelian), there is the action of G
on itself by left multiplication and by conjugation. So there we have two actions.
Johan Commelin (Jul 27 2019 at 10:22):
Of course this example is (somewhat) moot in the case of group cohomology, because you typically want the coefficients to be abelian.
Kevin Buzzard (Jul 27 2019 at 10:53):
I have an MSc student who is going to work on group cohomology in Lean this coming year.
Last updated: Dec 20 2023 at 11:08 UTC