Functional Programming Lecture 13 induction on lists Proof

  • Slides: 12
Download presentation
Functional Programming Lecture 13 induction on lists

Functional Programming Lecture 13 induction on lists

Proof by induction on Nat is an inductively defined set: base case: 0 :

Proof by induction on 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 are inductively defined sets: base case: [] : :

Proof by induction on 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 [] = 0 sumlist (x: xs) = x + sumlist xs double []

sumlist [] = 0 sumlist (x: xs) = x + sumlist xs double [] = [] double (x: xs) = (2*x) : double xs s. 0 s. 1 d. 0 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

Important Points Justify every step. Clearly state assumption. If you do not use the

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 x: xs ++ ys = x: (xs ++ ys)

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

[] ++ xs = xs x: xs ++ ys = x: (xs ++ ys)

[] ++ xs = xs x: xs ++ ys = x: (xs ++ ys) ++. 0 ++. 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 member

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

Theorem: For all finite xs, ys, and elements z. member (xs ++ ys )

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 don’t we need induction?

An Exercise prove that || is associative. Question: Why don’t we need induction?

rev [] = [] rev x: xs = rev xs ++ [x] rev. 0

rev [] = [] rev x: xs = rev xs ++ [x] rev. 0 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 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) = [x] ++ xs = x: xs QED by rev. 1+ by ass. by ++. 1+

rev [] = [] rev x: xs = rev xs ++ [x] rev. 0

rev [] = [] rev x: xs = rev xs ++ [x] rev. 0 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)) = rev(xs++ys) ++ [x] = (rev ys) ++ (rev xs) ++[x] r. h. s. (rev ys) ++ (rev x: xs)= (rev ys) ++ (rev xs) ++ [x] QED by ++. 1 by rev. 1 by ass. by rev. 1