9
9
module README.Design.Hierarchies where
10
10
11
11
open import Data.Sum.Base using (_⊎_)
12
+ open import Data.Product.Base using (_×_)
12
13
open import Level using (Level; _⊔_; suc)
13
14
open import Relation.Binary.Core using (_Preserves₂_⟶_⟶_)
14
15
@@ -120,6 +121,17 @@ LeftIdentity _≈_ e _∙_ = ∀ x → (e ∙ x) ≈ x
120
121
RightIdentity : Rel A ℓ → A → Op₂ A → Set _
121
122
RightIdentity _≈_ e _∙_ = ∀ x → (x ∙ e) ≈ x
122
123
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
+
123
135
-- Note that the types in `Definitions` modules are not meant to express
124
136
-- the full concept on their own. For example the `Associative` type does
125
137
-- 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 ⊔
164
176
-- fields of the `isMagma` record can be accessed directly; this
165
177
-- technique enables the user of an `IsSemigroup` record to use underlying
166
178
-- 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
+
168
194
-- This is not always possible, though. Consider the following definition
169
195
-- of preorders:
170
196
@@ -184,6 +210,54 @@ record IsPreorder {A : Set a}
184
210
-- `IsPreorder` record. Instead we provide an internal module and the
185
211
-- equality fields can be accessed via `Eq.refl` and `Eq.trans`.
186
212
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
+ }
187
261
188
262
------------------------------------------------------------------------
189
263
-- X.Bundles
0 commit comments