---
layout: default
title : "Setoid.Algebras.Products module (Agda Universal Algebra Library)"
date : "2021-07-03"
author: "agda-algebras development team"
---
#### Products of Setoid Algebras
This is the [Setoid.Algebras.Products][] module of the [Agda Universal Algebra Library][].
<!--
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
open import Overture using (π ; π₯ ; Signature)
module Setoid.Algebras.Products {π : Signature π π₯} where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( _,_ ; Ξ£-syntax )
open import Function using ( flip ; Func )
open import Level using( _β_ ; Level )
open import Relation.Binary using ( Setoid ; IsEquivalence ; Decidable )
open import Relation.Binary.PropositionalEquality using ( refl ; _β‘_ )
open import Relation.Unary using ( Pred ; _β_ )
open Func using ( cong ) renaming ( to to _β¨$β©_ )
open Setoid using ( Carrier ; _β_ ) renaming ( isEquivalence to isEqv )
open IsEquivalence using () renaming ( refl to reflE ; sym to symE ; trans to transE )
open import Overture using ( projβ; proj ; projIsOnto )
renaming ( IsSurjective to onto )
open import Setoid.Algebras.Basic {π = π} using ( Algebra ; _^_ ; ov ; π»[_] ; π[_])
private variable Ξ± Ο ΞΉ : Level
open Algebra
```
-->
```agda
β¨
: {I : Type ΞΉ }(π : I β Algebra Ξ± Ο) β Algebra (Ξ± β ΞΉ) (Ο β ΞΉ)
Domain (β¨
{I} π) =
record { Carrier = β i β π[ π i ]
; _β_ = Ξ» a b β β i β π»[ π i ] ._β_ (a i) (b i)
; isEquivalence =
record { refl = Ξ» i β reflE (isEqv π»[ π i ])
; sym = Ξ» x i β symE (isEqv π»[ π i ])(x i)
; trans = Ξ» x y i β transE (isEqv π»[ π i ])(x i)(y i)
}
}
Interp (β¨
{I} π) β¨$β© (f , a) = Ξ» i β (f ^ π i) (flip a i)
cong (Interp (β¨
{I} π)) (refl , f=g ) = Ξ» i β cong (Interp (π i)) (refl , flip f=g i )
```
#### Products of classes of Algebras
```agda
module _ {π¦ : Pred (Algebra Ξ± Ο) (ov Ξ±)} where
β : Type (ov (Ξ± β Ο))
β = Ξ£[ π¨ β (Algebra Ξ± Ο) ] π¨ β π¦
π : β β Algebra Ξ± Ο
π i = (projβ i)
class-product : Algebra (ov (Ξ± β Ο)) _
class-product = β¨
π
```
If `p : π¨ β π¦`, we view the pair `(π¨ , p) β β` as an *index* over the class,
so we can think of `π (π¨ , p)` (which is simply `π¨`) as the projection of the
product `β¨
π` onto the `(π¨ , p)`-th component.
#### Surjectivity of coordinate projections
Suppose `I` is an index type and `π : I β Algebra Ξ± Ο` is an indexed collection of algebras.
Let `β¨
π` be the product algebra defined above. Given `i : I`, consider the projection of `β¨
π`
onto the `i-th` coordinate. Of course this projection ought to be a surjective map from `β¨
π` onto
`π i`. However, this is impossible if `I` is just an arbitrary type. Indeed, we must have an
equality defined on `I` and this equality must be decidable, and we must assume that
each factor of the product is nonempty. In the [Setoid.Overture.Surjective][] module
we showed how to define a *decidable index type* in Agda. Here we use this to prove that the
projection of a product of algebras over such an index type is surjective.
```agda
module _ {I : Type ΞΉ}
{_β_ : Decidable{A = I} _β‘_}
{π : I β Algebra Ξ± Ο}
{πI : β i β π[ π i ] }
where
ProjAlgIsOnto : β{i} β Ξ£[ h β (π[ β¨
π ] β π[ π i ]) ] onto h
ProjAlgIsOnto {i} = (proj _β_ πI i) , projIsOnto _β_ πI
```