The goal of this lecture note is to demonstrate how nat_fold_right and list_fold_right abstract the pattern of recursive functions for Peano numbers and for lists.
For simplicity and ease of discourse, in this lecture note, all the implementations are lambda-dropped, i.e., each global main function calls a auxiliary function locally instead of globally.
Let us revisit the recursive addition function, which is defined recursively over its first argument:
Definition r_add (n m : nat) : nat :=
let fix visit i :=
match i with
O =>
m
| S i' =>
S (visit i')
end
in visit n.
Let us revisit the recursive power function, which is defined recursively over its second argument:
Definition r_power (x n : nat) : nat :=
let fix visit (i : nat) : nat :=
match i with
O =>
1
| S i' =>
x * visit i'
end
in visit n.
The two recursive functions above share a common pattern:
Definition ... (n : nat) ... :=
let fix visit i :=
match i with
O =>
...
| S n' =>
... (visit n') ...
end
in visit n.
Indeed,
So,
we obtain the following implementation:
Definition nat_fold_right (V : Type) (zero_case : V ) (succ_case : V -> V) (n : nat) : V :=
let fix visit i :=
match i with
O =>
zero_case
| S n' =>
succ_case (visit n')
end
in visit n.
Then, we can
to obtain the following defition of the addition function as an instance of nat_fold_right:
Definition r_add_right (n m : nat) : nat :=
nat_fold_right
nat
m
(fun ih => S ih)
n.
This implementation passes the unit tests.
Likewise, we can
to obtain the following defition of the power function as an instance of nat_fold_right:
Definition r_power_right (x n : nat) : nat :=
nat_fold_right
nat
1
(fun ih => x * ih)
n.
This implementation passes the unit tests.
Pablito: But how do we know, for example, that r_add_right implements the addition function?
Halcyon (thoughtful): Because testing only proves incorrectness, not correctness.
Edsger W. Dijkstra: How true, how true.
Mimer: Prof. Dijkstra! Thanks for dropping by!
Halcyon (raffish): So we should state and prove a theorem to the effect that r_power and r_power_right are equivalent.
Pablito: Right. That’s simple to do with the lambda-lifted versions of r_power and of nat_fold_right and their associated fold-unfold lemmas.
Mimer: That’s good to hear.
Pablito: But still.
[...calculate, see the resource file (for now)...]
Created [12 Apr 2024]