22-- The Agda standard library
33--
44-- Definition of subgroup via Group monomorphism
5+ --
6+ -- Based on Nathan van Doorn (Taneb)'s original PR
7+ -- https://github.com/agda/agda-stdlib/pull/2852
58------------------------------------------------------------------------
69
710{-# OPTIONS --safe --cubical-compatible #-}
@@ -17,14 +20,80 @@ open import Level using (suc; _⊔_)
1720private
1821 module G = Group G
1922
23+ ------------------------------------------------------------------------
24+ -- Definition
25+ --
26+ -- Fundamentally, this design is the same as in the above PR:
27+ -- a `SubX` is given by an `X` monomorphism...
28+ -- ... to be able to define such, the current library design requires
29+ -- * *some* `X`-domain of definition for the mono, here given by the
30+ -- placeholder name `domain`, which otherwise plays no role externally
31+ -- * an underlying bare ('raw') function defining the mono, here called
32+ -- (in search of a canonical name) `ι`, standing for 'injection'
33+ -- * the juice: that `ι` indeed defines a mono from the domain to the
34+ -- (underlying defining `rawX` subfield of the) top-level `X` module parameter
35+
2036record Subgroup c′ ℓ′ : Set (c ⊔ ℓ ⊔ suc (c′ ⊔ ℓ′)) where
2137 field
38+
39+ -- as above, this name is essentially arbitrary,
40+ -- exisitng solely to be mentioned in the third field below
41+
2242 domain : RawGroup c′ ℓ′
23- ι : _ → G.Carrier
43+
44+ -- this function (obviously) needs a source and target:
45+ -- * the target, for the sake of the third field, needs to be
46+ -- `Carrier` subfield of the top-level `X` module parameter
47+ -- * the source, however, really exists solely to give a type to `ι`
48+ -- and indeed, the typechecker can infer (from the third field)
49+ -- that this type *must* be the `Carrier` of the `RawX` `domain`
50+
51+ -- Taneb's design introduces a `private` module
52+ -- `private module H = RawGroup domain`
53+ -- for the sake of affording easy/easier named access to its
54+ -- `Carrier` field, and as preferable to the hideous explicit form
55+ -- `RawGroup.Carrier domain` which is the definiens of `H.Carrier`
56+
57+ -- Neither is necessary, but can be, and is, reconstructed by the
58+ -- typechecker by offering instead a placeholder, in exactly the same way
59+ -- that `domain` exists as a named field solely to express the dependency
60+ -- in the type of `ι-monomorphism`. In that sense, it is an ephemeral form
61+ -- derived from `domain`, which moreover will never play a role in client
62+ -- uses of this module, except as a typing constraint on any application
63+ -- of `ι`, a constraint which is already inherited (by definitional equality!)
64+ -- from the type of the `⟦_⟧` parameter to `IsXHomomorphism`...
65+
66+ ι : _ → G.Carrier -- where _ = RawGroup.Carrier domain
67+
68+ -- now all the pieces are in place, we can define what we *really* want
69+
2470 ι-monomorphism : IsGroupMonomorphism domain G.rawGroup ι
2571
72+ -- this is 'admin': any client module of `Subgroup` will likely want to
73+ -- refer to primitive *and* manifest subfields of `IsXMonmorphism`, so
74+ -- this is automatically made available to clients, but not `open`ed,
75+ -- so that such affordance is client-definable, as usual.
76+
2677 module ι = IsGroupMonomorphism ι-monomorphism
2778
79+ -- Similarly, but mathematically motivated: any client module of `Subgroup`
80+ -- will want access to *the `X` defined as the domain of the `IsXMonomorphism`*.
81+ -- But here, it is both automatically made available to clients, as above,
82+ -- *and* also `open`ed, so that its affordances are offered to any client
83+ -- via the 'canonical' names associated with the `X`/`IsX` bundle/structure
84+
85+ -- Taneb's design does this in two steps:
86+ -- * first, create the `IsX` structure, with name `isX`
87+ -- * second, create the `X` bundle` via `isX`
88+
89+ -- My own thinking on this has evolved: I would rather go straight for the
90+ -- bundle, from which `isX : IsX ...` is definable/exported by `open`.
91+ -- This avoids having to recapitulate the verbose telescope involved in any
92+ -- `IsX <telescope>` (and any design decisions/commitments around such things),
93+ -- or having to choose a name for the `isX` field, when, once again, all the
94+ -- heavy lifting is already made available by the `XHomomorphism` module, so
95+ -- for general DRY reasons, should not be repeated here.
96+
2897 group : Group _ _
2998 group = record { isGroup = isGroup ι-monomorphism G.isGroup }
3099
0 commit comments