```
(* square : int -> int
REQUIRES: true
ENSURES: square(n) => n^2
*)
fun square (n : int) : int = n*n
```

Below shows execution sequence:

```
square 7
=> [environment where square was defined] (fn (n:int) => n * n) 7
=> [env.] [7/n] (n * n)
=> [env.] [7/n] (7 * n)
=> [env.] [7/n] (7 * 7)
=> [env.] [7/n] 49 = 49 // once we got a value, environment is not important
```

or write it simpler:

```
square 7 // this is also fine
=> 7 * 7
=> 49
```

```
(* even: int -> bool
REQUIRES: true
ENSURES: even k (tailedarror => to value) {true if k even; false if k odd}
fun even (k : int) : bool = (k mod 2) = 0
*)
```

In `if e1 then e2 else e3 : t`

, `e2`

and `e3`

has to be the same type `t`

.

Equivalently, in the following code `e2`

and `e3`

has to be the same type.

```
case e1 of
true => e2
| false => e3
```

`If...then...else`

is only good for`bool`

Always use`case`

will ensure you don't make mistake

```
(* power: (int * int) -> int
REQUIRES: k >= 0
ENSURES: power (n, k) (tailedarror) n^k (where 0^0 = 1)
*)
fun power (n : int, 0 : int) : int = 1
| power (n, k) = n * power (n, k-1)
(* 3^7 = 3*3*3*3*3*3*3 *)
(* complexity: O(k) by recursive calls *)
fun power (n : int, 0 : int) : int = 1
| power (n, k) =
if even k
then square (power (n, k div 2))
else n * power (n, k-1)
(* 3^7 = 3(3(3*1)^2)^2 *)
(* complexity: O(log k) *)
```

Theorem: for all VALUES (because they might have on value) n:int, k:int where k>=0, power (n, k) |-> n^k Proof(1): By standard (weak) induction on k Base Case: k=0 WTS power (n, 0) |-> n^0 = 1 for all values n:int. power (n, 0) => 1 [first clause of power] Induction Step: prove k+1 holds using k hold induction hypothesis: power (n, k) -> n^k hold for all values n : int, for some fixed k >= 0 WTS: power (n, k+1) |-> n^{k+1} for all value n : int power (n, k+1) => n * power (n, k+1-1) [2nd clause] => n * power (n, k) [math] => n * n^k [induction hypothesis] => n^{k+1} [math] Since base case and inductive case are proved, the result follows by induction.

Proof(2): By strong induction on k Base Case: k=0 WTS power (n, 0) |-> n^0 = 1 for all values n:int. power (n, 0) => 1 [first clause of power] Induction Step: prove k hold using for all 0 <= k' < k, k' hold induction hypothesis: power (n, k) -> n^k hold for k' : int with 0 <= k' < k, and n : int WTS: power (n, k) |-> n^{k} for all value n : int power (n, k) => if even k then square (power (n, k div 2)) else n * power (n, k - 1) [2nd clause] case: k even: => square (power (n, k div 2)) [if-then-else] k = 2 * k' (for some k') and even k |=> true then k' = k/2, then k' < k [by math since k>0 and even] => square (power (n, k')) [math] => square (n^k') [IH] => n^k' * n^k' [by square] => n^k [math] case: k odd: => n * power (n, k-1) [if-then-else] ... (change k+1 to k)...

Structured induction is just induction but with code.

Type: t list (is a list for any type t)

Values: [v1, ..., vn] where each vi is a value of type t and n>= 0 - when n = 0, [] = nil

Expressions:
- `[]`

or `nil`

- `e :: es`

(where e:t and es: t list)
- `::`

is pronounced as "con" stands for concat
- `val 1::[2, 3] = [1, 2, 3]`

Type Checking rule:
- `[] : t list`

- `e :: es : t list`

if `e : t`

and `es : t list`

```
(*
length: int list -> int
REQUIRES: true
ENSURES: length L returns the length of L
*)
fun length ([] : int list) : int = 0
| length (x :: xs) = 1 + length xs
```

Theorem: length is total (ie. `length L |-> something`

, for all `L : int list`

)
Proof: by structure induction on L
Base Case: when `L = []`

WTS length `[] |-> something`

length []
=> 0 [first clause]
Inductive Step: when `L = x::xs`

for some value `x:int`

and `xs:int list`

IH: `length xs |-> v for some v`

WIS: `length (x::xs) |-> v' for some v'`

length (x::xs)
=> 1 + length xs [second clause]
=> 1 + v [IH]
=> (v + 1) [math]
let `v' = v+1`

, since `v`

is a type `int`

, `v'`

is value

Table of Content