---
layout: default
title : "Legacy.Base.Functions.Inverses module"
date : "2021-01-12"
author: "the agda-algebras development team"
---
### <a id="inverses">Inverses</a>
This is the [Legacy.Base.Functions.Inverses][] module of the [agda-algebras][] library.
```agda
{-# OPTIONS --cubical-compatible --exact-split --safe #-}
module Legacy.Base.Functions.Inverses where
open import Agda.Primitive using () renaming ( Set to Type )
open import Data.Product using ( _,_ ; Σ-syntax )
open import Level using ( Level ; _⊔_ )
open import Relation.Binary.PropositionalEquality
using ( _≡_ ; sym ; refl )
open import Relation.Unary using ( Pred ; _∈_ )
open import Overture.Basic using ( ∃-syntax ; ∣_∣ )
private variable a b : Level
```
We begin by defining an data type that represents the semantic concept of *inverse
image* of a function.
```agda
module _ {A : Type a}{B : Type b} where
data Image_∋_ (f : A → B) : B → Type (a ⊔ b) where
eq : {b : B} → (a : A) → b ≡ f a → Image f ∋ b
{-# WARNING_ON_USAGE Image_∋_ "Use Overture.Functions.Image_∋_ instead. Deprecated under #303; removal planned one minor cycle after #303 lands." #-}
{-# WARNING_ON_USAGE eq "Use Overture.Functions.eq instead. Deprecated under #303." #-}
open Image_∋_
Range : (A → B) → Pred B (a ⊔ b)
Range f b = ∃[ a ∈ A ] (f a) ≡ b
range : (A → B) → Type (a ⊔ b)
range f = Σ[ b ∈ B ] ∃[ a ∈ A ](f a) ≡ b
Image⊆Range : (f : A → B) → ∀ b → Image f ∋ b → b ∈ Range f
Image⊆Range f b (eq a x) = a , (sym x)
Range⊆Image : (f : A → B) → ∀ b → b ∈ Range f → Image f ∋ b
Range⊆Image f b (a , x) = eq a (sym x)
Imagef∋f : {f : A → B}{a : A} → Image f ∋ (f a)
Imagef∋f = eq _ refl
f∈range : {f : A → B}(a : A) → range f
f∈range {f} a = (f a) , (a , refl)
```
An inhabitant of `Image f ∋ b` is a dependent pair `(a , p)`, where `a : A` and
`p : b ≡ f a` is a proof that `f` maps `a` to `b`. Since the proof that `b` belongs
to the image of `f` is always accompanied by a witness `a : A`, we can actually
*compute* a (pseudo)inverse of `f`. For convenience, we define this inverse
function, which we call `Inv`, and which takes an arbitrary `b : B` and a
(*witness*, *proof*)-pair, `(a , p) : Image f ∋ b`, and returns the witness `a`.
```agda
Inv : (f : A → B){b : B} → Image f ∋ b → A
Inv f (eq a _) = a
{-# WARNING_ON_USAGE Inv "Use Overture.Functions.Inv instead. Deprecated under #303." #-}
[_]⁻¹ : (f : A → B) → range f → A
[ f ]⁻¹ (_ , (a , _)) = a
```
We can prove that `Inv f` is the (range-restricted) *right-inverse* of `f`, as
follows.
```agda
InvIsInverseʳ : {f : A → B}{b : B}(q : Image f ∋ b) → f(Inv f q) ≡ b
InvIsInverseʳ (eq _ p) = sym p
{-# WARNING_ON_USAGE InvIsInverseʳ "Use Overture.Functions.InvIsInverseʳ instead. Deprecated under #303." #-}
⁻¹IsInverseʳ : {f : A → B}{bap : range f} → f ([ f ]⁻¹ bap) ≡ ∣ bap ∣
⁻¹IsInverseʳ {bap = (_ , (_ , p))} = p
```
Of course, the "range-restricted" qualifier is needed because `Inf f` is not defined outside the range of `f`.
In a certain sense, `Inv f` is also a (range-restricted) *left-inverse*.
```agda
InvIsInverseˡ : ∀ {f a} → Inv f {b = f a} Imagef∋f ≡ a
InvIsInverseˡ = refl
⁻¹IsInverseˡ : ∀ {f a} → [ f ]⁻¹ (f∈range a) ≡ a
⁻¹IsInverseˡ = refl
```