t::=true∣false∣if t then telse t∣0∣succ t∣pred t∣iszero t
This can be implemented in Haskell as:
data Arith =
T
| F
| Ite Arith Arith Arith
| Zero
| Succ Arith
| Pred Arith
| Iszero Arith deriving (Show)
This is an inductive definition of a type of arithmetic expressions.
We will start by defining a function to compute the size of a term in Haskell:
size :: Arith -> Integer
size t =
case t of
T -> 1
size F -> 1
size (Ite a b c) -> 1 + size a + size b + size c
size Zero -> 1
size (Succ a) -> 1 + size a
size (Pred a) -> 1 + size a
size (Iszero a) -> 1 + size a
We can go on to define a depth
function, essentially calculating the depth of the abstract syntax tree:
We require two helper functions, max2
and max3
max2:: Integer -> Integer -> Integer
max2 a b
| a < b = b
| otherwise = a
max3 :: Integer -> Integer -> Integer
max3 a b c = max2 (max2 a b) c
depth :: Arith -> Integer
depth t
= case t of
T -> 1
F -> 1
Zero -> 1
Ite a b c -> 1 + max3 (depth a) (depth b) (depth c)
Succ a -> 1 + depth a
Pred a -> 1 + depth a
Iszero a -> 1 + depth a
**Note the inbuilt max
function could have been used instead of max2
Let us prove that depth t≤size t by induction on t
if t=T then depth T=1≤size T=1
if t=F then depth F=1≤size F =1
if t=Zero then depth Zero=1≤size Zero=1
if t=lte abc, assume depth a≤size a & depth b≤size b & depth c≤size c and prove depth(lte abc)≤size(lte abc)
depth(lte abc)=1+max(depth a)(max(depth b)(depth c))≤1+max(size a)(max(size b)(size c))≤1+size a+size b+size c=size (lte abc)
if t=Succ a then assume depth a≤size a and prove depth(Succ a)≤size(Succ a)
depth(Succ a)=1+depth a≤1+size a=size(Succ a)