# Recursion / Co-recursion

Matthias van der Hallen

The main idea is that co-recursion is the **dual** of recursion;

but in what sense?

Recursion

Co-recursion

- Terminology 'focuses' on the input (domain): an
**inductively**defined datatype - Inductively defined datatypes corresponds to a least fixpoint
- E.g. finite lists, finite trees, ... (data)

- Corresponds to a 'fold'

- Terminology 'focuses' on the output (codomain): a
**co-inductively**defined datatype - co-inductive datatype corresponds to a
**greatest fixpoint**- E.g. infinite lists (streams), infinite trees, ... (codata)

- Corresponds to an 'unfold'

### Example: Fibonacci

```
fibonacci :: Int -> Int
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n-1) + fibonacci (n-2)
```

A **recursive** definition of fibonacci **breaks down** its argument and returns a number

The idea of this being a 'fold' is probably more relatable by looking at natural numbers as a Peano numbers

(e.g. \(S(S(S(S Zero)))\))

### Example: Fibonacci

```
co-fibonacci :: Int -> Int -> [Int]
co-fibonacci a b = a `cons` co-fibonacci b (a+b)
```

A **co-recursive** definition of fibonacci **builds** an infinite list of fibonacci numbers by specifying **part** of the output

This function 'unfolds' a pair of integers into an (infinite) list of integers.

Note that in a language with support for codata, e.g. with lazy evaluation, infinite lists are not a problem.

(Literature suggests a link here with Prolog & *tail recursion module cons* - think of an accumulator - and possibly bottom-up / top-down through that)

### What if a function both **breaks** its arguments down and **builds **its result up?

Example: sorting functions with type

sort :: [a] -> [a]

- Can be seen as a fold, an unfold or a fold of an unfold (or vice versa)
- The paper 'A duality of sorts' views (pairs of) sorting algorithms as folds/unfolds of unfolds/folds.
- They make a nice comparison between insertion-sort and bubblesort

### More on datatypes & (un)-folding:

### The List type

`NatListF f = Nil | Cons Nat f`

Using ** open recursion** instead of

*, and*

**explicit recursion****specializing**to natural numbers, we can write

The least fixpoint is written as \( \mu \mathit{NatListF} \), while the greatest fixpoint is written as \( \nu \mathit{NatListF} \).

`List a = Nil | Cons a List`

We recognize this as the definition of a list:

`NatListF f = Nil | Cons Nat f`

The least fixpoint is written as \( \mu \mathit{NatListF} \), while the greatest fixpoint is written as \( \nu \mathit{NatListF} \).

Folding corresponds to using the isomorphism between \(\mu F\) and \(F (\mu F)\), as well as the **algebra **\(F a \rightarrow a\)

Unfolding corresponds to using the **co-algebra **\(a \rightarrow F a\), as well as the isomorphism between \(F (\nu F)\) and \(\nu F\)

### More on datatypes & (un)-folding:

### The List type

### Co-recursion: A (helpful?) visualization

A slightly more complicated unfolding (*futumorphism, **) can take into account the structure already unfolded.

(***): Every futumorphism can be rewritten into a (generalized) unfolding

Example: How to 'grow' a plant according to a complex set of rules based on one 'seed' value https://bit.ly/3ber6zv

Looking at the seed, it (randomly) branches, blooms or grows straight, leaving a new seed at the end of the structure

Note how at every 'iteration' (step), it looks as if we recurse through our **result **and expand where necessary; we **co-recurse**

### Does it correspond to the Owned Shares problem?

- By choosing a smart result datatype, we can probably provide a co-recursive view on the problem, but...
- it doesn't look like the process we want the solver to do, nor our semantical model

Nevertheless, I hope we all learned something

No (?)

### Although...

The paper "Mechanizing Coinduction and Corecursion in Higher-order Logic" states:

*"With corecursion, the case analysis is driven by the output list, rather than the input list."*

That definitely makes me think of function definitions like:

```
{
f(a,b) = pTrue <- p(a) & p(b).
f(a,b) = qTrue <- q(a) & q(b).
}
```

But I don't see it yet...

#### Recursion / co-Recursion

By Matthias van der Hallen

# Recursion / co-Recursion

- 730