Recursion. Tjark Weber. Functional Programming 1. Based on notes by Sven-Olof Nyström. Tjark Weber (UU) Recursion 1 / 37

Similar documents
Recursion. Lars-Henrik Eriksson. Functional Programming 1. Based on a presentation by Tjark Weber and notes by Sven-Olof Nyström

Chapter 3 Programming with Recursion

Functional Programming. Overview. Topics. Definition n-th Fibonacci Number. Graph

1.3. Conditional expressions To express case distinctions like

This session. Recursion. Planning the development. Software development. COM1022 Functional Programming and Reasoning

Higher-Order Functions

Inference rule for Induction

Exercise 1 ( = 24 points)

Recursion and Structural Induction

Programming Language Pragmatics

Introduction. chapter Functions

Sometimes it s good to be lazy

Inductive Data Types

Problem Set CVO 103, Spring 2018

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

Recursion Chapter 4 Self-Reference. Recursive Definitions Inductive Proofs Implementing Recursion

LECTURE 16. Functional Programming

Lecture 3: Recursion; Structural Induction

Exercise 1 ( = 18 points)

Lambda Calculus. Gunnar Gotshalks LC-1

Tail Recursion. ;; a recursive program for factorial (define fact (lambda (m) ;; m is non-negative (if (= m 0) 1 (* m (fact (- m 1))))))

Functional Programming and λ Calculus. Amey Karkare Dept of CSE, IIT Kanpur

Lambda Calculus LC-1

Denotational Semantics. Domain Theory

Combining Static and Dynamic Contract Checking for Curry

Functional Languages. Hwansoo Han

1KOd17RMoURxjn2 CSE 20 DISCRETE MATH Fall

Functional Programming. Big Picture. Design of Programming Languages

CSE-321 Programming Languages 2010 Midterm

Introduction to the Lambda Calculus

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

Recursion and Induction

CS1 Recitation. Week 2

Program Calculus Calculational Programming

Fall Recursion and induction. Stephen Brookes. Lecture 4

Announcements. CS243: Discrete Structures. Strong Induction and Recursively Defined Structures. Review. Example (review) Example (review), cont.

Exercise 1 ( = 22 points)

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

CS 310 Advanced Data Structures and Algorithms

MAT 243 Test 2 SOLUTIONS, FORM A

P1 Engineering Computation

APCS-AB: Java. Recursion in Java December 12, week14 1

CMPSCI 250: Introduction to Computation. Lecture #14: Induction and Recursion (Still More Induction) David Mix Barrington 14 March 2013

Haskell through HUGS THE BASICS

Formal Systems and their Applications

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Chapter 11 :: Functional Languages

ECE G205 Fundamentals of Computer Engineering Fall Exercises in Preparation to the Midterm

Lecture 10: Recursion vs Iteration

Functional Programming

Mathematical Induction

Organization of Programming Languages CS3200/5200N. Lecture 11

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Lecture 5: Lazy Evaluation and Infinite Data Structures

Induction and Recursion

15 212: Principles of Programming. Some Notes on Induction

Recursion. What is Recursion? Simple Example. Repeatedly Reduce the Problem Into Smaller Problems to Solve the Big Problem

CSE 20 DISCRETE MATH WINTER

CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Chapter 12

About coding style Spring February 9, 2004

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

CITS3211 FUNCTIONAL PROGRAMMING

Functional Programming

Fall 2018 Lecture N

CSE 215: Foundations of Computer Science Recitation Exercises Set #4 Stony Brook University. Name: ID#: Section #: Score: / 4

Lecture 2: The Basis of SML

Lecture Notes on Induction and Recursion

Reasoning about programs. Chapter 9 of Thompson

Introduction to the Theory of Computation, Sipser, PWS, ISBN X, 1996

Functional Programming Languages (FPL)

n λxy.x n y, [inc] [add] [mul] [exp] λn.λxy.x(nxy) λmn.m[inc]0 λmn.m([add]n)0 λmn.n([mul]m)1

15. Functional Programming

Functional Languages. CSE 307 Principles of Programming Languages Stony Brook University

Fundamental mathematical techniques reviewed: Mathematical induction Recursion. Typically taught in courses such as Calculus and Discrete Mathematics.

A catalogue of proofs that various sets, functions and relations are primitive recursive 26 February 2012 at 20:57

Streams. CS21b: Structure and Interpretation of Computer Programs Spring Term, 2004

Continuation Passing Style. Continuation Passing Style

CSE 505. Lecture #9. October 1, Lambda Calculus. Recursion and Fixed-points. Typed Lambda Calculi. Least Fixed Point

15 150: Principles of Functional Programming. Exceptions

ELEMENTARY NUMBER THEORY AND METHODS OF PROOF

CMSC 330: Organization of Programming Languages. Operational Semantics

Isabelle s meta-logic. p.1

Behavioral Equivalence

Programming Systems in Artificial Intelligence Functional Programming

A Theory of Parallel Computation The π-calculus

2009 HMMT Team Round. Writing proofs. Misha Lavrov. ARML Practice 3/2/2014

3.7 Denotational Semantics

CIS 500 Software Foundations Fall September 25

6.001 Notes: Section 4.1

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

Functional Programming

CSCC24 Functional Programming Scheme Part 2

Lambda calculus. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 6

CSc 372. Comparative Programming Languages. 2 : Functional Programming. Department of Computer Science University of Arizona

Fundamentals of Programming Session 13

T ::=Nat T T. zero : Nat. This rule can be instantiated for any type T, so it is actually a family of rules, one for each type.

Functional Programming

Contents. Chapter 1 SPECIFYING SYNTAX 1

Transcription:

Tjark Weber Functional Programming 1 Based on notes by Sven-Olof Nyström Tjark Weber (UU) Recursion 1 / 37

Background FP I / Advanced FP FP I / Advanced FP This course (Functional Programming I) (5 hp, period 1) introduces you to the fundamental concepts of functional programming. If you understand these concepts, you should find it quite easy to learn functional languages other than SML. The course Advanced Functional Programming (5 hp, period 2) deepens your knowledge in several functional languages (such as Haskell, Lisp, Erlang), their properties and application. You will carry out a small project in one of these languages (your choice). Tjark Weber (UU) Recursion 2 / 37

Background The Roots of Functional Programming The Roots of Functional Programming Imperative programming perhaps suggests itself: machine code is imperative; hardware contains memory whose state can change. A corresponding theoretical model is the Turing machine (1936). Also in 1936, Alonzo Church invented the lambda calculus, a simple (but very different) model for computation based on functions: t ::= x (λx. t) (t t) John McCarthy (LISP, 1958) and others recognized that this allows for a more declarative programming style, which focuses on what programs should accomplish, rather than describing how to go about it. Tjark Weber (UU) Recursion 3 / 37

Background When to Use Functional Programming? When to Use Functional Programming? Functional programming languages are Turing-complete: they can compute exactly the same functions as imperative and other languages. Always? Never? How do you choose a programming language, anyway? Tjark Weber (UU) Recursion 4 / 37

Background Strengths of Functional Programming Strengths of Functional Programming Unit testing: without global state, a function s return value only depends on its arguments. Each function can be tested in isolation. Concurrency: without modifiable data, programs can easily be parallelized (cf. Google s MapReduce). There is no risk of data races. Correctness: functional programs are much easier to reason about than programs that manipulate state.... Further reading: http://www.defmacro.org/ramblings/fp.html Tjark Weber (UU) Recursion 5 / 37

Recursion Tjark Weber (UU) Recursion 6 / 37

Recursion: Definition Recursion: Definition Recursion in computer science is a method where the solution to a problem depends on solutions to smaller instances of the same problem. http://en.wikipedia.org/wiki/recursion_%28computer_science%29 Tjark Weber (UU) Recursion 7 / 37

Recursion: Examples Recursion: Examples Summing over a list: fun sum [ ] = 0 sum ( x : : xs ) = x + sum xs Factorial function: fun f a c 0 = 1 f a c n = n f a c ( n 1) Tjark Weber (UU) Recursion 8 / 37

Recursion Replaces Loops Recursion Replaces Loops Recursion is one of the key concepts in functional programming. You will use (some form of) recursion wherever you might use a loop in an imperative language. Tjark Weber (UU) Recursion 9 / 37

Factorial Revisited Factorial Revisited fun f a c 0 = 1 f a c n = n f a c ( n 1) Tjark Weber (UU) Recursion 10 / 37

Factorial Revisited Factorial Revisited fun f a c 0 = 1 f a c n = n f a c ( n 1) What happens if n < 0? Tjark Weber (UU) Recursion 10 / 37

Factorial Revisited (cont.) Factorial Revisited (cont.) We test if the pre-condition n 0 is satisfied (defensive programming). fun f a c n = i f n < 0 then r a i s e Domain e l s e i f n = 0 then 1 e l s e n f a c ( n 1) Tjark Weber (UU) Recursion 11 / 37

Factorial Revisited (cont.) Factorial Revisited (cont.) We test if the pre-condition n 0 is satisfied (defensive programming). fun f a c n = i f n < 0 then r a i s e Domain e l s e i f n = 0 then 1 e l s e n f a c ( n 1) Useless test of the pre-condition at each recursive call. Tjark Weber (UU) Recursion 11 / 37

Factorial Revisited (cont.) Factorial Revisited (cont.) We introduce an auxiliary function. fun f a c n = l e t fun fac 0 = 1 fac n = n fac ( n 1) i n i f n < 0 then r a i s e Domain e l s e fac n end In fac: pre-condition verification In fac : no pre-condition verification Tjark Weber (UU) Recursion 12 / 37

Exponentiation: Specification and Construction Exponentiation: Specification and Construction Specification: fun expo x n TYPE: real > int > real PRE: n 0 POST: x n Tjark Weber (UU) Recursion 13 / 37

Exponentiation: Specification and Construction Exponentiation: Specification and Construction Specification: fun expo x n TYPE: real > int > real PRE: n 0 POST: x n Construction: Error case: n < 0: raise an exception Base case: n = 0: result is 1 Recursive case: n > 0: result is x n = x x n 1 = x expo x (n 1) Tjark Weber (UU) Recursion 13 / 37

Exponentiation: Program Exponentiation: Program fun expo x n = l e t fun expo x 0 = 1 expo x n = x expo x ( n 1) i n i f n < 0 then r a i s e Domain e l s e expo x n end Tjark Weber (UU) Recursion 14 / 37

Exponentiation: Program Exponentiation: Program fun expo x n = l e t fun expo x 0 = 1 expo x n = x expo x ( n 1) i n i f n < 0 then r a i s e Domain e l s e expo x n end Observation: the first argument of expo never changes; it is always x. Let s get rid of it. Tjark Weber (UU) Recursion 14 / 37

Exponentiation: Program (cont.) Exponentiation: Program (cont.) fun expo x n = l e t fun expo 0 = 1 expo n = x expo ( n 1) i n i f n < 0 then r a i s e Domain e l s e expo n end Tjark Weber (UU) Recursion 15 / 37

Triangle: Specification and Construction Triangle: Specification and Construction Specification: fun triangle a b TYPE: int > int > int PRE: (none) POST: b i=a i Tjark Weber (UU) Recursion 16 / 37

Triangle: Specification and Construction Triangle: Specification and Construction Specification: fun triangle a b TYPE: int > int > int PRE: (none) POST: b i=a i Construction: Error case: (none) Base case: a > b: result is 0 Recursive case: a b: result is b i=a i = a + ( b i=a+1 i) = a + triangle (a + 1) b Tjark Weber (UU) Recursion 16 / 37

Triangle: Program Triangle: Program fun t r i a n g l e a b = i f a > b then 0 e l s e a + t r i a n g l e ( a+1) b Tjark Weber (UU) Recursion 17 / 37

Recursion: Correctness Recursion: Correctness How do we know what a recursive program computes? Example: fun f 0 = 0 f n = 1 + f ( n 1) What does f compute? Tjark Weber (UU) Recursion 18 / 37

Recursion: Correctness Recursion: Correctness How do we know what a recursive program computes? Example: fun f 0 = 0 f n = 1 + f ( n 1) What does f compute? Answer: f (n) = n, if n 0 Seems reasonable, but how do we prove it? Tjark Weber (UU) Recursion 18 / 37

The Axiom of Induction The Axiom of Induction If P is a property of natural numbers such that 1 P(0) is true, and 2 whenever P(k) is true, then P(k + 1) is true, then P(n) is true for all natural numbers n. Tjark Weber (UU) Recursion 19 / 37

Example: Proof by Induction Example: Proof by Induction fun f 0 = 0 f n = 1 + f ( n 1) We want to prove that f (n) = n for all natural numbers n. (So, in this example, P(n) f (n) = n.) 1 Base case P(0): f (0) = 0 by definition. 2 Inductive step: assume that P(k) is true, i.e., f (k) = k. Then f (k + 1) = 1 + f ((k + 1) 1) = 1 + f (k) = 1 + k = k + 1 hence P(k + 1) is true. It follows that f (n) = n for all natural numbers n. Tjark Weber (UU) Recursion 20 / 37

Another Example: Proof by Induction Another Example: Proof by Induction fun g 0 = 0 g n = n + g ( n 1) What does g compute? Tjark Weber (UU) Recursion 21 / 37

Another Example: Proof by Induction Another Example: Proof by Induction fun g 0 = 0 g n = n + g ( n 1) What does g compute? Answer: g(n) = n(n+1) 2 Proof (by induction): exercise. Tjark Weber (UU) Recursion 21 / 37

Complete Induction Complete Induction Complete induction is a variant of induction that allows to assume the induction hypothesis not just for the immediate predecessor, but for all smaller natural numbers. If P is a property of natural numbers such that 1 P(0) is true, and 2 whenever P(j) is true for all j k, then P(k + 1) is true, then P(n) is true for all natural numbers n. Exercise: show that complete induction is equivalent to the axiom of induction. Tjark Weber (UU) Recursion 22 / 37

Correctness of Functional Programs Correctness of Functional Programs Suppose we want to show that a recursive function fun f x =... f (... )... satisfies some property P(x, f (x)). Solution: 1 Show that f terminates (for all values of x that we care about). 2 Assume that all recursive calls f (x ) satisfy the property P(x, f (x )), and show P(x, f (x)). (This is just an induction proof in disguise.) Tjark Weber (UU) Recursion 23 / 37

Example: Correctness of Functional Programs Example: Correctness of Functional Programs fun f a c 0 = 1 f a c n = n f a c ( n 1) We want to show that P(n, fac(n)) fac(n) = 1 n holds. 1 For now, let s just assume that fac terminates for all n 0. (We ll actually prove this in a few minutes.) 2 Assume that the recursive call satisfies P(n 1, fac(n 1)) fac(n 1) = 1 (n 1). Now show P(n, fac(n)): (i) If n = 0, fac(0) = 1 as required. (ii) If n > 0, fac(n) = n fac(n 1) = n (1 (n 1)) = 1 n using algebraic properties of multiplication. Tjark Weber (UU) Recursion 24 / 37

Example: Correctness of Functional Programs Construction Methodology Objective: construction of a (recursive) SML program computing the function f : D R given a specification S Methodology: 1 Case analysis: identify error, base, and recursive case(s) 2 Partial correctness: show that the base case returns the correct result; show that the recursive cases return the correct result, assuming that all recursive calls do 3 Termination: find a suitable variant Tjark Weber (UU) Recursion 25 / 37

Example: Correctness of Functional Programs Variants A variant for a (recursive) function is any expression over the function s parameters that takes values in some ordered set A such that there are no infinite descending chains v 0 > v 1 >... in A, and for any recursive call, the variant decreases strictly. Often, A = {0, 1, 2,... }. Variants are often simple: e.g., a non-negative integer given by a parameter or the size of some input data. But watch out for the more difficult cases! Tjark Weber (UU) Recursion 26 / 37

Example: Variants Example: Variants fun f a c 0 = 1 f a c n = n f a c ( n 1) Variant for fac n: Tjark Weber (UU) Recursion 27 / 37

Example: Variants Example: Variants fun f a c 0 = 1 f a c n = n f a c ( n 1) Variant for fac n: n This variant is a non-negative integer (thus, there are no infinite descending chains) that strictly decreases with every recursive call (n 1 < n). Tjark Weber (UU) Recursion 27 / 37

Forms of Recursion Forms of Recursion So far: simple recursion (one recursive call only, some variant is decremented by one) corresponds to simple induction Other forms of recursion: Complete recursion Multiple recursion Mutual recursion Nested recursion Recursion on a generalized problem Tjark Weber (UU) Recursion 28 / 37

Example: Complete Recursion Example: Complete Recursion Specification: fun int div a b TYPE: int > int > int int PRE: a 0 and b > 0 POST: (q, r) such that a = q b + r and 0 r < b Tjark Weber (UU) Recursion 29 / 37

Example: Complete Recursion Example: Complete Recursion Specification: fun int div a b TYPE: int > int > int int PRE: a 0 and b > 0 POST: (q, r) such that a = q b + r and 0 r < b Construction: Error case: a < 0 or b 0: raise an exception Base case: a < b: since a = 0 b + a, result is (0, a) Recursive case: a b: since a = q b + r iff a b = (q 1) b + r, int div (a b) b will compute q 1 and r Tjark Weber (UU) Recursion 29 / 37

Example: Complete Recursion (cont.) Example: Complete Recursion (cont.) fun i n t d i v a b = l e t fun i n t d i v a b = i f a < b then ( 0, a ) e l s e l e t v a l ( q, r ) = i n t d i v ( a b ) b i n ( q+1, r ) end i n i f a < 0 o r e l s e b <= 0 then r a i s e Domain e l s e i n t d i v a b end To prove correctness of int div, we need an induction hypothesis not only for a 1, but for all values less than a, i.e., we need complete induction. Tjark Weber (UU) Recursion 30 / 37

Example: Multiple Recursion Example: Multiple Recursion Definition of the Fibonacci numbers: fib(0) = 0 fib(1) = 1 fib(n) = fib(n 1) + fib(n 2) Tjark Weber (UU) Recursion 31 / 37

Example: Multiple Recursion Example: Multiple Recursion Definition of the Fibonacci numbers: fib(0) = 0 fib(1) = 1 fib(n) = fib(n 1) + fib(n 2) Specification: fun fib n TYPE: int > int PRE: n 0 POST: fib(n) Tjark Weber (UU) Recursion 31 / 37

Example: Multiple Recursion Example: Multiple Recursion Definition of the Fibonacci numbers: fib(0) = 0 fib(1) = 1 fib(n) = fib(n 1) + fib(n 2) Specification: fun fib n TYPE: int > int PRE: n 0 POST: fib(n) Program: fun f i b n = l e t fun f i b 0 = 0 f i b 1 = 1 f i b n = f i b ( n 1) + f i b ( n 2) i n i f n < 0 then r a i s e Domain e l s e f i b n end Tjark Weber (UU) Recursion 31 / 37

Example: Mutual Recursion Example: Mutual Recursion Recognizing even and odd natural numbers: fun even n TYPE: int > bool PRE: n 0 POST: true iff n is even fun odd n TYPE: int > bool PRE: n 0 POST: true iff n is odd Program: fun even 0 = t r u e even n = odd ( n 1) and odd 0 = f a l s e odd n = even ( n 1) Mutual recursion requires simultaneous declaration of the functions and global correctness reasoning. Tjark Weber (UU) Recursion 32 / 37

Example: Nested Recursion Example: Nested Recursion The Ackermann function: fun a c k e r 0 m = m+1 a c k e r n 0 = a c k e r ( n 1) 1 a c k e r n m = a c k e r ( n 1) ( a c k e r n (m 1)) Variant? Tjark Weber (UU) Recursion 33 / 37

Example: Nested Recursion Example: Nested Recursion The Ackermann function: fun a c k e r 0 m = m+1 a c k e r n 0 = a c k e r ( n 1) 1 a c k e r n m = a c k e r ( n 1) ( a c k e r n (m 1)) Variant? The pair (n, m) N N, where N N is ordered lexicographically: (a, b) < lex (c, d) iff a < c or (a = c and b < d). Tjark Weber (UU) Recursion 33 / 37

Recursion on a Generalized Problem Recursion on a Generalized Problem Example: recognizing prime numbers Specification: fun prime n TYPE: int > bool PRE: n > 0 POST: true iff n is a prime number Tjark Weber (UU) Recursion 34 / 37

Recursion on a Generalized Problem Recursion on a Generalized Problem Example: recognizing prime numbers Specification: fun prime n TYPE: int > bool PRE: n > 0 POST: true iff n is a prime number Construction: It seems impossible to directly determine whether n is prime if we only know whether n 1 is prime. We thus need to find a function that is more general than prime, in the sense that prime is a special case of this function, and for which a recursive program can be constructed. Tjark Weber (UU) Recursion 34 / 37

Recursion on a Generalized Problem (cont.) Recursion on a Generalized Problem (cont.) Specification of the generalized function: fun indivisible n low up TYPE: int > int > int > bool PRE: n, low, up 1 POST: true iff n has no divisor in {low,..., up} Tjark Weber (UU) Recursion 35 / 37

Recursion on a Generalized Problem (cont.) Recursion on a Generalized Problem (cont.) Specification of the generalized function: fun indivisible n low up TYPE: int > int > int > bool PRE: n, low, up 1 POST: true iff n has no divisor in {low,..., up} Construction: Base case: low > up: result is true Recursive case: low up: n has no divisor in {low,..., up} iff low does not divide n and n has no divisor in {low + 1,..., up} Tjark Weber (UU) Recursion 35 / 37

Recursion on a Generalized Problem (cont.) Recursion on a Generalized Problem (cont.) Program: fun i n d i v i s i b l e n low up = low > up o r e l s e ( n mod low <> 0 andalso i n d i v i s i b l e n ( low + 1) up ) Tjark Weber (UU) Recursion 36 / 37

Recursion on a Generalized Problem (cont.) Recursion on a Generalized Problem (cont.) Program: fun i n d i v i s i b l e n low up = low > up o r e l s e ( n mod low <> 0 andalso i n d i v i s i b l e n ( low + 1) up ) Now the function prime is essentially a special case of indivisible : fun prime n = i f n <= 0 then r a i s e Domain e l s e n > 1 andalso i n d i v i s i b l e n 2 ( n 1) Tjark Weber (UU) Recursion 36 / 37

Standard Methods of Generalization Standard Methods of Generalization Let the recursive function take additional parameters, so that the problem we want to solve is a special case. Let the recursive function return more information than is required in the problem statement. Tjark Weber (UU) Recursion 37 / 37

Standard Methods of Generalization Standard Methods of Generalization Let the recursive function take additional parameters, so that the problem we want to solve is a special case. Let the recursive function return more information than is required in the problem statement. Exercise: implement a function that computes fib(n) with a number of recursive calls proportional to n. Tjark Weber (UU) Recursion 37 / 37