Skip to content

Setoid.Functions.Injective

Injective functions on setoids

This is the Setoid.Functions.Injective module of the agda-algebras library.

We say that a function f : A β†’ B from one setoid (A , β‰ˆβ‚€) to another (B , β‰ˆβ‚) is injective (or monic) provided the following implications hold: βˆ€ aβ‚€ a₁ if f ⟨$⟩ aβ‚€ β‰ˆβ‚ f ⟨$⟩ a₁, then aβ‚€ β‰ˆβ‚€ a₁.

{-# OPTIONS --cubical-compatible --exact-split --safe #-}

open import Relation.Binary using ( Setoid )

module Setoid.Functions.Injective where

-- Imports from Agda and the Agda Standard Library -------------
open import Agda.Primitive    using ( _βŠ”_ ; Level )  renaming ( Set to Type )
open import Function.Bundles  using ( Injection )    renaming ( Func to _⟢_ )
open import Function.Base     using ( _∘_ ; id )
open import Relation.Binary   using ( _Preserves_⟢_ )
open import Relation.Binary   using ( Rel )

open import Function.Definitions using (Injective)

-- Imports from agda-algebras -----------------------------------------------
open import Setoid.Functions.Basic     using ( 𝑖𝑑 ) renaming ( _βŠ™_ to _βŸ¨βŠ™βŸ©_ )
open import Setoid.Functions.Inverses  using ( Image_βˆ‹_ ; Inv )

private variable a b c Ξ± Ξ² Ξ³ ℓ₁ β„“β‚‚ ℓ₃ : Level

A function f : A ⟢ B from one setoid (A , β‰ˆβ‚€) to another (B , β‰ˆβ‚) is called injective provided βˆ€ aβ‚€ a₁, if f ⟨$⟩ aβ‚€ β‰ˆβ‚ f ⟨$⟩ a₁, then aβ‚€ β‰ˆβ‚€ a₁. The Agda Standard Library defines a type representing injective functions on bare types and we use this type (called Injective) to define our own type representing the property of being an injective function on setoids (called IsInjective).

module _ {𝑨 : Setoid a Ξ±}{𝑩 : Setoid b Ξ²} where
  open Setoid 𝑨 using ()               renaming (Carrier to A; _β‰ˆ_ to _β‰ˆβ‚_)
  open Setoid 𝑩 using ( trans ; sym )  renaming (Carrier to B; _β‰ˆ_ to _β‰ˆβ‚‚_)

  open Injection {From = 𝑨}{To = 𝑩} using ( function ; injective ) renaming (to to _⟨$⟩_)
  open _⟢_ {a = a}{Ξ±}{b}{Ξ²}{From = 𝑨}{To = 𝑩} renaming (to to _⟨$⟩_ )
  IsInjective : (𝑨 ⟢ 𝑩) β†’ Type (a βŠ” Ξ± βŠ” Ξ²)
  IsInjective f = Injective _β‰ˆβ‚_ _β‰ˆβ‚‚_ (_⟨$⟩_ f)

  open Image_βˆ‹_

  -- Inverse of an injective function preserves setoid equalities
  LeftInvPreservesβ‰ˆ :  (F : Injection 𝑨 𝑩) {bβ‚€ b₁ : B}
    (u : Image (function F) βˆ‹ bβ‚€) (v : Image (function F) βˆ‹ b₁)
    β†’ bβ‚€ β‰ˆβ‚‚ b₁ β†’ Inv (function F) u β‰ˆβ‚ Inv (function F) v

  LeftInvPreservesβ‰ˆ F (eq aβ‚€ xβ‚€) (eq a₁ x₁) bb = Goal
    where
    faβ‚€β‰ˆfa₁ : F ⟨$⟩ aβ‚€ β‰ˆβ‚‚ F ⟨$⟩ a₁
    faβ‚€β‰ˆfa₁ = trans (sym xβ‚€) (trans bb x₁)

    Goal : aβ‚€ β‰ˆβ‚ a₁
    Goal = injective F faβ‚€β‰ˆfa₁

Proving that the composition of injective functions is again injective is simply a matter of composing the two assumed witnesses to injectivity. (Note that here we are viewing the maps as functions on the underlying carriers of the setoids; an alternative for setoid functions, called ∘-injective, is proved below.)

module _
  {A : Type a}(_β‰ˆβ‚_ : Rel A Ξ±)
  {B : Type b}(_β‰ˆβ‚‚_ : Rel B Ξ²)
  {C : Type c}(_β‰ˆβ‚ƒ_ : Rel C Ξ³) where

  ∘-injective-bare : {f : A β†’ B} {g : B β†’ C}
    β†’ Injective _β‰ˆβ‚_ _β‰ˆβ‚‚_ f β†’ Injective _β‰ˆβ‚‚_ _β‰ˆβ‚ƒ_ g
    β†’ Injective _β‰ˆβ‚_ _β‰ˆβ‚ƒ_ (g ∘ f)

  ∘-injective-bare finj ginj = finj ∘ ginj

module _ {𝑨 : Setoid a Ξ±}{𝑩 : Setoid b Ξ²}{π‘ͺ : Setoid c Ξ³} where

  βŠ™-injective :  (f : 𝑨 ⟢ 𝑩)(g : 𝑩 ⟢ π‘ͺ)
   β†’             IsInjective f β†’ IsInjective g
   β†’             IsInjective (g βŸ¨βŠ™βŸ© f)

  βŠ™-injective _ _ finj ginj = finj ∘ ginj

  βŠ™-injection : Injection 𝑨 𝑩 β†’ Injection 𝑩 π‘ͺ β†’ Injection 𝑨 π‘ͺ
  βŠ™-injection fi gi = record
   { to = to gi ∘ to fi
   ; cong = cong gi ∘ cong fi
   ; injective = βŠ™-injective (function fi) (function gi) (injective fi) (injective gi)
   }
   where open Injection

id-is-injective : {𝑨 : Setoid a Ξ±} β†’ IsInjective{𝑨 = 𝑨}{𝑨} 𝑖𝑑
id-is-injective = id