module Functions.Recursive where

Import list

open import Data.Bool using (Bool; true; false)
open import Data.Nat using (; suc; zero)

Functions can be recursive as well, which is essential for working on sets that were defined recursively. In this case, a common approach is to define an alternative for each of the constructors and when the constructor is recursive then the function itself shall also be probably recursive.

_+_: Addition

Consider the previous definition of the type, where we had the following constructors with the following types:

zero : ℕ
suc : ℕ → ℕ

Note that this was done along the lines of the mathematical definition of the Peano arithmetic. Consider also the definion of how to calculate the sum of two natural numbers with this representation:


Now consider the same definition in Agda:

_+_ :     
zero  + n = n
suc m + n = suc (m + n)

infixl 6 _+_


Define the following functions:

pred  : ℕ → ℕ      -- predecessor (pred 0 = 0)

infixl 6 _∸_
_∸_   : ℕ → ℕ → ℕ  -- subtraction (0 ∸ n = n)

infixl 7 _*_
_*_   : ℕ → ℕ → ℕ  -- multiplication

infixl 6 _⊔_
_⊔_   : ℕ → ℕ → ℕ  -- maximum

infixl 7 _⊓_
_⊓_   : ℕ → ℕ → ℕ  -- minimum

⌊_/2⌋ : ℕ → ℕ      -- half (⌊ 1 /2⌋ = 0)

odd   : ℕ → Bool   -- is odd

even  : ℕ → Bool   -- is even

Mutual definitions

It is possible to define functions mutually, like we did for sets. As an example, consider the mutual definition of the even and odd functions:

odd : ℕ → Bool

even : ℕ → Bool
even zero    = true
even (suc n) = odd n

odd zero    = false
odd (suc n) = even n


Define the following functions mutually:

_≡?_  :     Bool  -- is equal
_≤?_  :     Bool  -- is less than or equal

Binary representation of

Import the binary representation of natural numbers:

open import Sets.Recursive using (ℕ⁺; one; double; double+1; ℕ₂; zero; id)


Define a conversion function of the following type:

from : ℕ₂    -- hint: use _*_

Note that the from function shall define a reverse function of the following isomorphism between and ℕ₂ (later we will prove that from is an isomorphism):

zero zero
suc zero id one
suc (suc zero) id (double one)
suc (suc (suc zero)) id (double+1 one)
... ...

Later we will see how to define the same conversion in the other direction.


Define and some operations on it (such as _+_, _-_, _*_).

Binary trees

data BinTree : Set where
  leaf : BinTree
  node : BinTree  BinTree  BinTree


Define (recursive) mirroring of binary trees, that is a function with the following type:

mirror : BinTree → BinTree