99module README.Design.Hierarchies where
1010
1111open import Data.Sum.Base using (_⊎_)
12+ open import Data.Product.Base using (_×_)
1213open import Level using (Level; _⊔_; suc)
1314open import Relation.Binary.Core using (_Preserves₂_⟶_⟶_)
1415
@@ -120,6 +121,17 @@ LeftIdentity _≈_ e _∙_ = ∀ x → (e ∙ x) ≈ x
120121RightIdentity : Rel A ℓ → A → Op₂ A → Set _
121122RightIdentity _≈_ e _∙_ = ∀ x → (x ∙ e) ≈ x
122123
124+ Identity : Rel A ℓ → A → Op₂ A → Set _
125+ Identity _≈_ e ∙ = (LeftIdentity _≈_ e ∙) × (RightIdentity _≈_ e ∙)
126+
127+ LeftZero : Rel A ℓ → A → Op₂ A → Set _
128+ LeftZero _≈_ z _∙_ = ∀ x → (z ∙ x) ≈ z
129+
130+ DistributesOverʳ : Rel A ℓ → Op₂ A → Op₂ A → Set _
131+ DistributesOverʳ _≈_ _*_ _+_ =
132+ ∀ x y z → ((y + z) * x) ≈ ((y * x) + (z * x))
133+
134+
123135-- Note that the types in `Definitions` modules are not meant to express
124136-- the full concept on their own. For example the `Associative` type does
125137-- not require the underlying relation to be an equivalence relation.
@@ -164,7 +176,21 @@ record IsSemigroup {A : Set a} (≈ : Rel A ℓ) (∙ : Op₂ A) : Set (a ⊔
164176-- fields of the `isMagma` record can be accessed directly; this
165177-- technique enables the user of an `IsSemigroup` record to use underlying
166178-- records without having to manually open an entire record hierarchy.
167- --
179+
180+ -- Thus, we may incrementally build monoids out of semigroups by adding an
181+ -- `Identity` for the underlying operation, as follows:
182+
183+ record IsMonoid {A : Set a} (≈ : Rel A ℓ) (∙ : Op₂ A) (ε : A) : Set (a ⊔ ℓ) where
184+ field
185+ isSemigroup : IsSemigroup ≈ ∙
186+ identity : Identity ≈ ε ∙
187+
188+ open IsSemigroup isSemigroup public
189+
190+ -- where the `open IsSemigroup isSemigroup public` ensures, transitively,
191+ -- that both `associative` and (all the subfields of) `isMagma` are brought
192+ -- into scope.
193+
168194-- This is not always possible, though. Consider the following definition
169195-- of preorders:
170196
@@ -184,6 +210,54 @@ record IsPreorder {A : Set a}
184210-- `IsPreorder` record. Instead we provide an internal module and the
185211-- equality fields can be accessed via `Eq.refl` and `Eq.trans`.
186212
213+ -- More generally, we quickly face the issue of how to model structures
214+ -- in which there are *two* (or more!) interacting algebraic substructures
215+ -- which *share* an underlying `IsEquivalence` in terms of which their
216+ -- respective axiomatisations are expressed.
217+
218+ -- For example, in the family of `IsXRing` structures, there is a
219+ -- fundamental representation problem, namely how to associate the
220+ -- multiplicative structure to the additive, in such a way as to avoid
221+ -- the possibility of ambiguity as to the underlying `IsEquivalence`
222+ -- substructure which is to be *shared* between the two operations.
223+
224+ -- The simplest instance of this is `IsNearSemiring`, defined as:
225+
226+ record IsNearSemiring
227+ {A : Set a} (≈ : Rel A ℓ) (+ * : Op₂ A) (0# : A) : Set (a ⊔ ℓ) where
228+ field
229+ +-isMonoid : IsMonoid ≈ + 0#
230+ *-cong : * Preserves₂ ≈ ⟶ ≈ ⟶ ≈
231+ *-assoc : Associative ≈ *
232+ distribʳ : DistributesOverʳ ≈ * +
233+ zeroˡ : LeftZero ≈ 0# *
234+
235+ -- where a multiplicative `IsSemigroup *` *acts* on the underlying
236+ -- `+-isMonoid` (whence the distributivity), but is not represented
237+ -- *directly* as a primitive `*-isSemigroup : IsSemigroup *` field.
238+
239+ -- Rather, the `stdlib` designers have chosen to privilege the underlying
240+ -- *additive* structure over the multiplicative: thus for structure
241+ -- `IsNearSemiring` defined here, the additive structure is declared
242+ -- via a field `+-isMonoid : IsMonoid + 0#`, while the multiplicative
243+ -- is given 'unbundled' as the *components* of an `IsSemigroup *` structure,
244+ -- namely as an operation satisfying both `*-cong : Congruent₂ *` and
245+ -- also `*-assoc : Associative *`, from which the corresponding `IsMagma *`
246+ -- and `IsSemigroup *` are then immediately derivable:
247+
248+ open IsMonoid +-isMonoid public using (isEquivalence)
249+
250+ *-isMagma : IsMagma ≈ *
251+ *-isMagma = record
252+ { isEquivalence = isEquivalence
253+ ; ∙-cong = *-cong
254+ }
255+
256+ *-isSemigroup : IsSemigroup ≈ *
257+ *-isSemigroup = record
258+ { isMagma = *-isMagma
259+ ; associative = *-assoc
260+ }
187261
188262------------------------------------------------------------------------
189263-- X.Bundles
0 commit comments