Presentation is loading. Please wait.

# Functional Programming Lecture 13 - induction on lists.

## Presentation on theme: "Functional Programming Lecture 13 - induction on lists."— Presentation transcript:

Functional Programming Lecture 13 - induction on lists

Proof by induction on Nat Nat is an inductively defined set: base case: 0 :: Nat, ind. case: if n:: Nat, then n+1 :: Nat. extremal: nothing else belongs to Nat. To prove a property of Nat, P(x), we use the Principle of Induction: base case: prove P(0), ind. case: Prove P(n+1), assuming P(n).

Proof by induction on Lists Lists are inductively defined sets: base case: [] :: [a], ind. case: if xs :: [a], and x::a, then (x:xs) :: [a]. extremal: nothing else belongs to [a]. To prove a property of [a], P(xs), we use the Principle of (Structural) Induction: base case: prove P([]), ind. case: Prove P(x:xs), assuming P(xs). The format of the proof is extremely important. Best illustrated by examples.

sumlist [] = 0s.0 sumlist (x:xs) = x + sumlist xs s.1 double [] = []d.0 double (x:xs) = (2*x) : double xs d.1 Theorem: For all finite xs. sumlist (double xs) = 2* (sumlist xs) Proof: By induction on xs. Base Case: Prove sumlist (double [] ) = 2 *(sumlist []). l.h.s. sumlist (double []) = sumlist [] by d.0 = 0 by s.0 r.h.s. 2 * (sumlist []) = 2 * 0 by s.0 = 0 by arith. Ind Case: Assume sumlist (double xs ) = 2 *(sumlist xs). Prove sumlist (double x:xs ) = 2 *(sumlist x:xs). l.h.s. sumlist (double x:xs ) = sumlist ((2*x) : double xs) by d.1 = (2*x) + sumlist (double xs) by s.1 = (2*x) + 2 *(sumlist xs) by ass. = 2 * ( x+sumlist xs) by arith. = 2 * (sumlist x:xs) by s.1 QED

Important Points Justify every step. Clearly state assumption. If you do not use the assumption in a step, then you are not doing a proof by induction! Work on the l.h.s., or the r.h.s., or both.

[] ++ xs = xs ++.0 x:xs ++ ys = x:(xs ++ ys) ++.1 Theorem: For all finite xs. xs ++ [] = xs. ([] is a right identity for ++) Proof: By induction on xs. Base Case: Prove [] ++ [] = []. l.h.s. [] ++ [] = [] by ++.0 Ind Case: Assume xs ++ [] = xs. Prove x:xs ++ [] = x:xs. l.h.s. x:xs ++ [] = x:(xs ++[]) by ++.1 = x:xs by ass. QED

[] ++ xs = xs ++.0 x:xs ++ ys = x:(xs ++ ys) ++.1 Theorem: For all finite xs,yz,zs. xs ++ (ys ++ zs) = (xs ++ ys) ++ zs (++ is associative) Proof: By induction on xs. Base Case: Prove [] ++ (ys ++zs) = ([] ++ ys) ++ zs l.h.s. [] ++ (ys ++zs) = ys ++ zs by ++.0 = ([] ++ ys) ++zs by ++.0 Ind Case: Assume xs ++ (ys ++ zs) = (xs ++ ys) ++ zs Prove x:xs ++ (ys ++ zs) = (x:xs ++ ys) ++ zs l.h.s. x:xs ++ (ys ++ zs) = x:(xs ++(ys++zs)) by ++.1 = x:((xs ++ys)++zs) by ass. =x:(xs++ys) ++zs by ++.1 = (x:xs ++ ys) ++zs by ++.1 QED

member :: String -> Char -> Bool member [] y = False m.0 member (x:xs) y = (x==y) || member xs y m.1 False || x = x or.0 True || x = True or.1

Theorem: For all finite xs, ys, and elements z. member (xs ++ ys ) z = member xs z || member ys z. Proof: By induction on xs. Base Case: Prove member ([] ++ ys ) z = member [] z || member ys z. l.h.s. member ([] ++ ys ) z = member ys z by ++.0 r.h.s. member [] z || member ys z = False || member ys z by m.1 = member ys z by or.0 Ind Case: Assume member (xs ++ ys ) z = member xs z || member ys z. Prove member (x:xs ++ ys ) z = member (x:xs) z || member ys z. l.h.s. member (x:xs ++ ys ) z = member (x:(xs ++ ys))z by ++.1 = (x==z) || member (xs ++ ys) z by m.1 = (x==z) || (member xs z || member ys z) by ass. = ((x==z) || member xs z) || member ys z) by || assoc = member (x:xs) z || member ys z by m.1 QED

An Exercise prove that || is associative. Question: Why dont we need induction?

rev [] = [] rev.0 rev x:xs = rev xs ++ [x] rev. 1 Theorem: For all finite xs. rev (rev xs) = xs Proof: By induction on xs. Base Case: Prove rev (rev []) = [] l.h.s. rev (rev []) = rev [] by rev.0 = [] by rev.0 Ind Case: Assume rev (rev xs) = xs. Prove rev (rev x:xs) =x:xs. l.h.s. rev (rev x:xs) = rev (rev xs ++ [x]) by rev.1 = rev ([x]) ++ rev (rev xs) by ?? = [x] ++ rev (rev xs) by rev.1+ = [x] ++ xs by ass. = x: xs by ++.1+ QED

rev [] = [] rev.0 rev x:xs = rev xs ++ [x] rev. 1 Theorem: For all finite xs,ys. rev (xs ++ys) = (rev ys) ++ (rev xs) Proof: By induction on xs. Base Case: Prove rev ([] ++ ys) = (rev []) ++ (rev ys). l.h.s. rev ([] ++ ys) = rev ys by ++.0 = [] ++ rev ys by ++.0 =(rev []) ++ (rev ys) by rev.0 Ind Case: Assume rev (xs ++ys) = (rev ys) ++ (rev xs). Prove rev (x:xs ++ys) = (rev ys) ++ (rev x:xs). l.h.s. rev (x:xs ++ys) = rev (x:(xs++ys)) by ++.1 = rev(xs++ys) ++ [x] by rev.1 = (rev ys) ++ (rev xs) ++[x] by ass. r.h.s. (rev ys) ++ (rev x:xs)= (rev ys) ++ (rev xs) ++ [x] by rev. 1 QED

Download ppt "Functional Programming Lecture 13 - induction on lists."

Similar presentations

Ads by Google