Skip to content

Conversation

@Taneb
Copy link
Member

@Taneb Taneb commented Oct 31, 2025

Add definition of ideals and quotient rings. Based on #2854. Taken from #2729

Copy link
Contributor

@jamesmckinna jamesmckinna left a comment

Choose a reason for hiding this comment

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

All looks good. Lots of stylistic nitpicking though!

Comment on lines 20 to 22
record Ideal c′ ℓ′ : Set (c ⊔ ℓ ⊔ suc (c′ ⊔ ℓ′)) where
field
-- a (two sided) ideal is exactly a subbimodule of R considered as a bimodule over itself
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd put the comment above the record declaration, and even embellish it to:

Suggested change
record Ideal c′ ℓ′ : Set (c ⊔ ℓ ⊔ suc (c′ ⊔ ℓ′)) where
field
-- a (two sided) ideal is exactly a subbimodule of R considered as a bimodule over itself
------------------------------------------------------------------------
-- Definition
-- a (two-sided) ideal is exactly a sub-bimodule of R considered as a bimodule over itself
record Ideal c′ ℓ′ : Set (c ⊔ ℓ ⊔ suc (c′ ⊔ ℓ′)) where
field

record Ideal c′ ℓ′ : Set (c ⊔ ℓ ⊔ suc (c′ ⊔ ℓ′)) where
field
-- a (two sided) ideal is exactly a subbimodule of R considered as a bimodule over itself
subbimodule : Subbimodule (TU.bimodule {R = R}) c′ ℓ′
Copy link
Contributor

Choose a reason for hiding this comment

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

I personally find the parametrisation in TensorUnit to make this kind of thing more ugly to read than is wholly necessary (I'd perhaps downstream even reconsider some of the implicit vs. explicit quantification there), and, because Subbimodule already takes an {R : Ring _ _} parameter, I'd be tempted to write instead:

Suggested change
subbimodule : Subbimodule (TU.bimodule {R = R}) c′ ℓ′
subbimodule : Subbimodule {R = R} (TU.bimodule) c′ ℓ′

which would then permit the earlier import of TU to actually be handled in place as

open import Algebra.Module.Construct.TensorUnit using (bimodule)

I'd even be tempted to go further: conventionally, the canonical name for the tensor unit (wrt whatever tensor product structure) is \bI, so I'd even make this a renaming import

open import Algebra.Module.Construct.TensorUnit renaming (bimodule to 𝕀)

but this is being hyper-nitpicky! (maybe!?)

Comment on lines 24 to 25
open import Algebra.Properties.Semiring semiring
open import Algebra.Properties.Ring R
Copy link
Contributor

Choose a reason for hiding this comment

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

A pity that we don't (yet) have it so that the second presupposes the first cf. #2804 ?

open import Algebra.Structures
open import Function.Definitions using (Surjective)
open import Level
open import Relation.Binary.Reasoning.Setoid setoid
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto. should this be part of the API exported by Algebra.Properties.X? Do we ever invoke algebraic properties not in a context where we have access to equational reasoning wrt that algebra?

open import Algebra.Properties.Semiring semiring
open import Algebra.Properties.Ring R
open import Algebra.Structures
open import Function.Definitions using (Surjective)
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused, AFAICT?

renaming (≋-∙-cong to ≋-+-cong; ≋-⁻¹-cong to ≋‿-‿cong)

open import Algebra.Definitions _≋_
open import Algebra.Morphism.Structures using (IsRingHomomorphism)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be bumped up above the private block?

Copy link
Contributor

@JacquesCarette JacquesCarette left a comment

Choose a reason for hiding this comment

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

We're a picky bunch... nice stuff!

open import Level
open import Relation.Binary.Reasoning.Setoid setoid

≋-*-cong : Congruent₂ _*_
Copy link
Contributor

Choose a reason for hiding this comment

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

I would be tempted to use a local module (I forget the syntax for doing just inside the proof part) where I is opened so that all these qualifiers can go away. It's an idiom used a lot in 1lab that I need to integrate into my own Agda.

}
; *-cong = ≋-*-cong
; *-assoc = λ x y z ≈⇒≋ (*-assoc x y z)
; *-identity = record
Copy link
Contributor

Choose a reason for hiding this comment

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

as this is 'just' a pair, use _,_ instead of a record? And maybe also eta contract?

Copy link
Member Author

Choose a reason for hiding this comment

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

I personally find lambdas on the left hand side of an operator (such as _,_) really ugly, so I use the record syntax to avoid it where I can...

Copy link
Contributor

Choose a reason for hiding this comment

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

I can get on board with that. There are a variety of generalized composition combinators in Function.Base that might let you not use a lambda, if you feel so inclined.

{ fst = λ x ≈⇒≋ (*-identityˡ x)
; snd = λ x ≈⇒≋ (*-identityʳ x)
}
; distrib = record
Copy link
Contributor

Choose a reason for hiding this comment

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

_,_ would work here too (but not eta)

@Taneb Taneb force-pushed the quotient-rings branch 2 times, most recently from 6b6e16e to 2e5866b Compare November 3, 2025 09:23
Comment on lines +15 to +21
private module I = Ideal I
open I using (ι; normalSubgroup)
Copy link
Contributor

Choose a reason for hiding this comment

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

You can, somewhat counterintuitively, simplify this to

Suggested change
private module I = Ideal I
open I using (ι; normalSubgroup)
private open module I = Ideal I using (ι; normalSubgroup)

project-isHomomorphism : IsRingHomomorphism rawRing quotientRawRing project
project-isHomomorphism = record
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
project-isHomomorphism : IsRingHomomorphism rawRing quotientRawRing project
project-isHomomorphism = record
project-isRingHomomorphism : IsRingHomomorphism rawRing quotientRawRing project
project-isRingHomomorphism = record

As with #2854 maybe have the algebra name X in the name, as well as the type?

open I using (ι; normalSubgroup)

open import Algebra.Construct.Quotient.Group +-group normalSubgroup public
using (_≋_; _by_; ≋-refl; ≋-sym; ≋-trans; ≋-isEquivalence; ≈⇒≋; quotientIsGroup; quotientGroup; project; project-surjective)
Copy link
Contributor

Choose a reason for hiding this comment

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

How much of this list actually needs to be exported?
Yes, you use ≋-refl in particular, as well as ≈⇒≋ but the rest of the generic ≋-isEquivalence structure is not used, and could be recreated if needed from quotientGroup? (variations on the theme of #2391 )

Copy link
Member Author

Choose a reason for hiding this comment

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

I do actually want most of these to be reexported! They might not be used in this module but I deliberately make them part of this module's interface

Copy link
Contributor

Choose a reason for hiding this comment

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

See also the discussion #2859 (comment)

Making these names public pollutes the namespace, when they can be obtained, with the 'usual' names, by suitable open directives on the constructed quotient group. My personal view (with qualified names to avoid ambiguity/clash if necessary) is that the extra names are a DRY failure.

Comment on lines +42 to +48
{ Carrier = Carrier
; _≈_ = _≋_
; _+_ = _+_
; _*_ = _*_
; -_ = -_
; 0# = 0#
; 1# = 1#
}
Copy link
Contributor

@jamesmckinna jamesmckinna Nov 5, 2025

Choose a reason for hiding this comment

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

Suggested change
{ Carrier = Carrier
; _≈_ = _≋_
; _+_ = _+_
; _*_ = _*_
; -_ = -_
; 0# = 0#
; 1# = 1#
}
{ RawRing R.rawRing hiding (_≈_)
; _≈_ = _≋_
}

avoids redundant DRY ...?

Comment on lines +54 to +55
{ isGroup = quotientIsGroup
; comm = λ x y ≈⇒≋ (+-comm x y)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't need to create, nor import, quotientIsGroup here; can be recreated on the fly:

Suggested change
{ isGroup = quotientIsGroup
; comm = λ x y ≈⇒≋ (+-comm x y)
}
{ isGroup = isGroup
; comm = λ x y ≈⇒≋ (+-comm x y)
} where open Group quotientGroup using (isGroup)

quotientRing : Ring c (c ⊔ ℓ ⊔ c′)
quotientRing = record { isRing = quotientIsRing }
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly, can we inline the definition of quotientIsRing here?

@jamesmckinna
Copy link
Contributor

In lieu of any further review comments, please see #2859 (purely!) as a comparison point, and feel free to grab anything from there which you might find useful... it just seemed the easiest way to encapsulate all the thoughts I had had about your groups-rings-modules development

------------------------------------------------------------------------
-- Definition

-- a (two sided) ideal is exactly a subbimodule of R considered as a bimodule over itself
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with @JacquesCarette on #2859

Suggested change
-- a (two sided) ideal is exactly a subbimodule of R considered as a bimodule over itself
-- a (two sided) ideal is exactly a sub-bimodule of R considered as a bimodule over itself

Comment on lines +30 to +31
normalSubgroup : NormalSubgroup c′ ℓ′
normalSubgroup = record
Copy link
Contributor

@jamesmckinna jamesmckinna Nov 10, 2025

Choose a reason for hiding this comment

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

I'd move this to Subbimodule, via Sub.AbelianGroup, as in #2859

@jamesmckinna jamesmckinna mentioned this pull request Nov 12, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants