
<center><img src="https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/recursivite-meme.png " width=512 height=auto /> </center>  

### 5.1. Simple functions
To create a recursive function we have to use this structure

```Ocaml
(*normal function*)
# let f = expr -> 1) evaluate expr ; 2) create & link f to the result

(*recursiv function*)
# let rec f = expr -> 1) create f ; 2) evaluate expr ; 3) link f to the result
```

**Exmple with factorial function**
```Ocaml
# let rec fact = function 
	| 0 -> 1
	| n -> n * fact(n-1)

# fact 4;;
-: int = 24
```
![Alt](https://gitea.louisgallet.fr/lgallet/epicours/raw/branch/main/Algo/S%C3%A9minaire/assets/fact%20function%20response.png)
> ⚠️ CAML have a call stack limite (it will block with stack overflow if the limit is reach)

**Basic expression**
```Ocaml
let rec f params = 
	if stop condition then 
		stop expression
	else
		recursive expression 
```

To write a recurvise function we need two things
1) There always is a stop case
2) The parameters of a recursive call are different then its parent call, and go towards  the stop condition

### 5.2. Down
```Ocaml
# let rec countdown n = 
	if n < 0 then
		()
	else
		begin
			print_int n ;
			print_newline();
			countdown(n-1);
		end;;
val countdown = int -> unit = ()

# countdown 3;;
3
2
1
- : unit = ()
```
Flowchart of CAML evaluation
```mermaid
flowchart LR

A[ctd 3] --> B[ctd 2] --> C[ctd 1] --> D[ctd 0] --> E[ctd -1] --> F[ ] --> E --> D --> C --> B --> A
```
> ctd is countdown

## 5.3. Several recursive calls
A function that have several recursive calls is defined like this
$$
Fn = {1 -> \text{if } n\eqslantless{1} \brace{Fn+1+Fn+2} }
$$
**Fibonacci functions**
```Ocaml
let rec fibonacci n =
	if n = 0 then
		0
	else if n = 1 then
		1
	else
		fibonacci(n-1) + fibonacci(n-2);;

let rec odd n = 
	if n = 0 then
		false
	else
		even (n-1);;

and even n =
	if n = 0 then
		true
	else
		add (n-1);;
val add : int -> bool = <fun>
val even : int -> bool = <fun>
```

An accumulator is a variable used to stock temporary the intermediaries results of a recursive operation. In CAML the syntax for the accumulator (`inv`) is: (exemple with reverse_int exercise. See 4.9 - b)
```Ocaml
# let reverse_int =
	let rec rev inv = function
		| 0 -> inv
		| n -> rev (inv*10 + n mod 10)(n/10)
	in rev 0 n;;
```

## 4.3. Complexity
Exemple with egypt (4.10) vs multiply (4.6):
```Ocaml
# let multiply a b =
	let (a,b) = if a > b then
		(a,b) else
		(b,a)
	in let rec mult = function
		| 0 -> 0
		| b -> a +mult (b-1)
	in mult b;;
```

The best algorithm in term of complexity is the parameter that is constant/linear or logarithmic. If you have an exponential algorithm, you can put it in trash :)

**Exemple with fibonacci algorithm**
```Ocaml
# let rec fibo = function 
	0|1 -> 1
	| n -> fibo (n-1) + fibo(n-2);;
```


| |res|how (for human) ?|How (for function) ?|
|:----:|:----:|:----:|:----:|
|0|1|def|1 call|
|1|1|def|1 call|
|2|2|+|3 calls|
|3|3|+|5 calls|
|4|5|+|9 calls|
|5|8|+|15 calls|
|6|13|+|14 calls|
| | |$0(n)$|$O(2^n)$|


<center><img src="https://imgur.com/6OWREOm.png" height=400 width=auto/></center>

This function is not optimize because the number of calls is growing exponentially. 
A good function will be:
```Ocaml
# let fibo n = 
	let rec fib i fi fi_1 = 
		if n <= i then
			fi
		else
			fib (i+1)(fi+fi_1)fi
	in fib 1 1 1
```
