Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

[WIP] subgroups and homomorphisms#94

Closed
kim-em wants to merge 19 commits intoleanprover-community:masterfrom
kim-em:group_theory
Closed

[WIP] subgroups and homomorphisms#94
kim-em wants to merge 19 commits intoleanprover-community:masterfrom
kim-em:group_theory

Conversation

@kim-em
Copy link
Copy Markdown
Collaborator

@kim-em kim-em commented Apr 8, 2018

This is some basic material on finite group theory, done by my student Mitchell Rowett in January.

There's also some further material on quotient groups, and the first isomorphism theorem, which can follow in a later PR.

Comment thread algebra/group/default.lean Outdated

theorem inv (a : α) : (f a)⁻¹ = f a⁻¹ :=
inv_eq_of_mul_eq_one $ by simp [(H a a⁻¹).symm, one H]
@[simp] theorem inv (a : α) : f a⁻¹ = (f a)⁻¹ :=
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We thought the inv theorem was better stated in this direction, as it is telling you how to compute f on the inverse of something, rather than telling you how to compute the inverse of f of something. (That is, it's about the homomorphism, not the group structure.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense.

Comment thread algebra/group/default.lean Outdated

instance comp : is_group_hom (g ∘ f) := {
hom_mul := λ x y, calc
g (f (x * y)) = g (f x * f y) : by rw mul f -- Why doesn't `simp` work here?
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone could explain why simp doesn't work here, that would be great.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mention above, the hom theorems can't be simp lemmas because they have nothing to key on - the head of the expression is a variable. You can write simp [mul f, one f] etc though.

Comment thread algebra/group/coset.lean Outdated
infix * := lcoset
infix * := rcoset

end coset_notation
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work. You can't namespace notations in lean 3, and this will ruin multiplication everywhere else. You must use local notation, but then they can't be the same symbol. Try *l and *r or something.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 8d602aa and 2b7b65b.

Comment thread algebra/group/default.lean Outdated
include w

theorem mul : ∀ a b : α, f (a * b) = f a * f b := H
@[simp] theorem mul : ∀ a b : α, f (a * b) = f a * f b := w.hom_mul
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can't be simp lemmas, they don't work since f is a variable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish I understood simp better. I thought that simp was fine with "(precondition) -> X = Y", isn't that what is going on here? forall f, H (saying f is a group hom), a and b, blah?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why mul won't work (well[1]) as a simp lemma is not because there is a precondition, but because the function symbol f is not a constant (it is a variable here).

The simplifier indexes the available lemmas by the head function symbol of the left-hand side, for example foo 0 = 1 would be indexed by the name foo. If the simplifier then sees a subterm of the form foo (a*b), it will only look for simp lemmas for the name foo and will not find the mul lemma.

[1] I believe that you can use mul as a simp lemma if the homomorphism that you want to rewrite is a local constant, but I haven't tested it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment thread algebra/group/default.lean Outdated
def is_group_hom (f : α → β) : Prop :=
∀ a b : α, f (a * b) = f a * f b
class is_group_hom (f : α → β) :=
(hom_mul : ∀ a b : α, f (a * b) = f a * f b)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you make this a Type? We really want is_* things to be Props

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: 0 indent

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turned is_group_hom back into a Prop in ca77526, although this caused two typeclass inference problems I don't understand: see #94 (review).

Style issues hopefully all fixed in 91693ec.

Comment thread algebra/group/default.lean Outdated

theorem inv (a : α) : (f a)⁻¹ = f a⁻¹ :=
inv_eq_of_mul_eq_one $ by simp [(H a a⁻¹).symm, one H]
@[simp] theorem inv (a : α) : f a⁻¹ = (f a)⁻¹ :=
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense.

Comment thread algebra/group/default.lean Outdated

instance comp : is_group_hom (g ∘ f) := {
hom_mul := λ x y, calc
g (f (x * y)) = g (f x * f y) : by rw mul f -- Why doesn't `simp` work here?
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mention above, the hom theorems can't be simp lemmas because they have nothing to key on - the head of the expression is a variable. You can write simp [mul f, one f] etc though.

Comment thread algebra/group/coset.lean Outdated
exact mul_mem this h,
simp
}
end
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: 2 indent spaces, braces on same line

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 91693ec.

Comment thread algebra/group/subgroup.lean Outdated
attribute [simp] subgroup.one_mem
subgroup.inv_mem
subgroup.mul_mem
normal_subgroup.normal
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these should be simp lemmas, simp isn't really designed for this sort of thing. If it helps here, use local attribute [simp] instead.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made this local for now, but could just inline them into the simps that use them if that's preferred.

Comment thread algebra/group/subgroup.lean Outdated
one_mul := λ ⟨x, hx⟩, subtype.eq $ one_mul x,
mul_one := λ ⟨x, hx⟩, subtype.eq $ mul_one x,
inv := λ ⟨x, hx⟩, ⟨x⁻¹, inv_mem hx⟩,
mul_left_inv := λ ⟨x, hx⟩, subtype.eq $ mul_left_inv x }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: 2 indent

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 91693ec.

Comment thread algebra/group/subgroup.lean Outdated
def trivial (G : Type u) [group G] : set G := {1}

instance trivial_in : normal_subgroup (trivial G) :=
by refine {..}; simp {contextual := tt}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why in?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've given all the instances better names (to me at least; I know people think I name things verbosely) in 808e1a0. (Sorry, that should have been two separate commits.)

Comment thread algebra/group/subgroup.lean Outdated
end

lemma inj_iff_trivial_kernel {f : G → H} [is_group_hom f] : function.injective f ↔ kernel f = trivial G :=
⟨trivial_kernel_of_inj, inj_of_trivial_kernel⟩
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline the last two lemmas into this one

Comment thread algebra/group/subgroup.lean Outdated
⟨inv_ker_one, one_ker_inv⟩

lemma inv_iff_ker (f : G → H) [w : is_group_hom f] (a b : G) : f a = f b ↔ a * b⁻¹ ∈ kernel f :=
⟨@inv_ker _ _ _ _ f w _ _, @ker_inv _ _ _ _ f w _ _⟩ -- TODO: I don't understand why I can't just write ⟨inv_ker, ker_inv⟩ here. (This gives typeclass errors; it can't find `w`.)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why typeclass inference is failing here (after I turned is_group_hom back into a Prop). Help appreciated!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think f needs to be explicit in the previous several lemmas. Also none of them should be [simp], for the same reasons as the is_group_hom lemmas: it only works as a simp lemma if the LHS starts with a constant, not f.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've removed all the [simp]s, and made all the fs explicit.

Comment thread algebra/group/subgroup.lean Outdated

-- Examples of subgroups
@[simp]
def trivial (G : Type u) [group G] : set G := {1}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you want this definition to be [simp], if you intend on using it at all. This will just make it unfold everywhere, making things like trivial_normal useless.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread algebra/group/subgroup.lean Outdated
variables [group G] [group H]

@[simp]
def kernel (f : G → H) [is_group_hom f] : set G := preimage f (trivial H)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also shouldn't be [simp].

Comment thread algebra/group/subgroup.lean Outdated
one_mem := ⟨1, one_mem S, one f⟩,
inv_mem := assume a ⟨b, hb, eq⟩,
⟨b⁻¹, inv_mem hb, by rw inv f; simp *⟩
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: braces on same line, before and after. Also leave off the subgroup . if it can be inferred (which should always be the case, assuming you have stated the target type of the theorem).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread algebra/group/subgroup.lean Outdated
end

lemma inj_iff_trivial_kernel {f : G → H} [w : is_group_hom f] : function.injective f ↔ kernel f = trivial G :=
⟨@trivial_kernel_of_inj _ _ _ _ f w, @inj_of_trivial_kernel _ _ _ _ f w⟩ -- TODO again, why can't it find w by itself?
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make f explicit in this and the last two lemmas, and that should fix your typeclass problem. You may be getting a sense for why I thought making is_group_hom a typeclass doesn't gain you that much, except possibly chains like is_group_hom.comp.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it doesn't fix it. Commit coming in a moment.

Comment thread algebra/group/subgroup.lean Outdated
universes u v
variables {G : Type u} {H : Type v}

class subgroup [group G] (S : set G) : Prop :=
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Kenny for pointing this out: @johoelzl did this after Mitchell had finished for the summer, and neither of us had seen it in the meantime.

Rather than immediately update this PR so that it uses this code, I'll send an intermediate commit that modifies the existing subgroup.lean so that it uses is_subgroup as a typeclass. After everyone's had a chance to comment on that, I'll "rebase" Mitchell's work onto Johannes's.

@johoelzl
Copy link
Copy Markdown
Collaborator

I submitted my changes to subgroup. There is apparently also a small conflict in algebra/group.

Comment thread algebra/group.lean Outdated

end add_comm_group

variables [group α] {β : Type*} [group β]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why you want to have it in this order?
Usually the order is: types, type classes instances, values, proofs. This does not always work due to dependencies. But in this case it should be no difference.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just to keep related things together. I have no real sense that this is valuable enough to break the usual ordering you indicated, so I will change it back.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is a good heuristic to keep types first, as this is often the problem when something can not be inferred.

Comment thread group_theory/coset.lean Outdated
def left_coset [has_mul G] (a : G) (S : set G) : set G := image (λ x, a * x) S
def right_coset [has_mul G] (S : set G) (a : G) : set G := image (λ x, x * a) S

infix ` *l `:70 := left_coset
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a lot of *x notation nowadays, do we really want to fix this to left and right coset? how about changing this to local infix notation?

Copy link
Copy Markdown
Collaborator Author

@kim-em kim-em Apr 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this to local. (I think Mario earlier suggested the same, sorry for missing it.)

Comment thread group_theory/subgroup.lean Outdated

instance center_normal : normal_subgroup (center G) := {
one_mem := by simp [center],
mul_mem := begin
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

begin should be at the next line, and the list of tactic calls inside indented by 2.
And everywhere further down too.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

@johoelzl
Copy link
Copy Markdown
Collaborator

Hi Scott, I have a couple of stylistic fixes. If you want I can merge this pull request and do the changes myself.

@kim-em
Copy link
Copy Markdown
Collaborator Author

kim-em commented Apr 11, 2018

@johoelzl, that would be great! I will read your fixes afterwards.

@johoelzl
Copy link
Copy Markdown
Collaborator

Closed with fa86d34. I squashed your commits into one.

@johoelzl johoelzl closed this Apr 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants