Chapter 3 Programming with Recursion

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

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

Chapter 3 Linear Structures: Lists

Chapter 3 Linear Structures: Lists

Chapter 2 SML, a Functional Programming Language

2.1. Expressions. Chapter 2 SML, a Functional Programming Language. Integers. Interacting with ML

2.1. Expressions. Chapter 2 ML, a Functional Programming Language. Integers. Interacting with ML

Inference rule for Induction

MAT 243 Test 2 SOLUTIONS, FORM A

15 150: Principles of Functional Programming. Exceptions

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

Problem Set CVO 103, Spring 2018

1.3. Conditional expressions To express case distinctions like

ASSIGNMENT 4 SOLUTIONS

15 212: Principles of Programming. Some Notes on Induction

Fall Recursion and induction. Stephen Brookes. Lecture 4

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

Recursion vs Induction

Lecture Notes on Induction and Recursion

Mathematical Induction

CSE-321 Programming Languages 2010 Midterm

Recursion vs Induction. CS3330: Algorithms The University of Iowa

A Brief Introduction to Standard ML

Lecture 2: The Basis of SML

Discrete Mathematics Lecture 4. Harper Langston New York University

Fall Lecture 3 September 4. Stephen Brookes

CS 310 Advanced Data Structures and Algorithms

Lecture 3: Recursion; Structural Induction

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

Inductive Data Types

Agenda. The worst algorithm in the history of humanity. Asymptotic notations: Big-O, Big-Omega, Theta. An iterative solution

Reduction & Recursion Overview

Solutions to the Second Midterm Exam

15 150: Principles of Functional Programming Sorting Integer Lists

General Computer Science (CH ) Fall 2016 SML Tutorial: Practice Problems

Functions. CS10001: Programming & Data Structures. Sudeshna Sarkar Professor, Dept. of Computer Sc. & Engg., Indian Institute of Technology Kharagpur

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

1KOd17RMoURxjn2 CSE 20 DISCRETE MATH Fall

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

Scan Scheduling Specification and Analysis

Names and Functions. Chapter 2

11/2/2017 RECURSION. Chapter 5. Recursive Thinking. Section 5.1

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

COE428 Lecture Notes Week 1 (Week of January 9, 2017)

ELEMENTARY NUMBER THEORY AND METHODS OF PROOF

CS 173, Running Time Analysis, Counting, and Dynamic Programming. Tandy Warnow

Fall 2018 Lecture N

SML A F unctional Functional Language Language Lecture 19

Recursion Chapter 8. What is recursion? How can a function call itself? How can a function call itself?

Reading 8 : Recursion

Sometimes it s good to be lazy

Anatomy of a static method, S&W, 2.1, figure page 188. Class.name or just name Scope, S&W, 2.1, figure page 189. Overloading

Higher-Order Functions

About coding style Spring February 9, 2004

CSci 1113, Fall 2015 Lab Exercise 4 (Week 5): Write Your Own Functions. User Defined Functions

Functional Programming

Chapter 1 Programming: A General Overview

A quick introduction to SML

Algorithm Design: GCD

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

ELEMENTARY NUMBER THEORY AND METHODS OF PROOF

Chapter 6 Abstract Datatypes

Outline. Introduction. 2 Proof of Correctness. 3 Final Notes. Precondition P 1 : Inputs include

P1 Engineering Computation

CS109A ML Notes for the Week of 1/16/96. Using ML. ML can be used as an interactive language. We. shall use a version running under UNIX, called

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

Recursion. Chapter 5

Algorithm Analysis. (Algorithm Analysis ) Data Structures and Programming Spring / 48

Programming & Data Structure Laboratory. Day 2, July 24, 2014

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

Recursion Chapter 8. What is recursion? How can a function call itself? How can a function call itself? contains a reference to itself.

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

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

Functional Programming Languages (FPL)

Recursion CSCI 136: Fundamentals of Computer Science II Keith Vertanen Copyright 2011

Two Approaches to Algorithms An Example (1) Iteration (2) Recursion

Recursion. Overview. Mathematical induction. Hello recursion. Recursion. Example applications. Goal: Compute factorial N! = 1 * 2 * 3...

Loops / Repetition Statements

Lecture 6: Arithmetic and Threshold Circuits

HW 1 CMSC 452. Morally DUE Feb 7 NOTE- THIS HW IS THREE PAGES LONG!!! SOLUTIONS THROUGOUT THIS HW YOU CAN ASSUME:

Richard Feynman, Lectures on Computation

CS 3512, Spring Instructor: Doug Dunham. Textbook: James L. Hein, Discrete Structures, Logic, and Computability, 3rd Ed. Jones and Barlett, 2010

Program Calculus Calculational Programming

CSC236H Lecture 5. October 17, 2018

HOMEWORK FILE SOLUTIONS

Number System. Introduction. Natural Numbers (N) Whole Numbers (W) Integers (Z) Prime Numbers (P) Face Value. Place Value

CS 3410 Ch 7 Recursion

Solutions to Homework 10

Begin at the beginning

Lecture 10: Recursion vs Iteration

CITS3001. Algorithms, Agents and Artificial Intelligence. Semester 2, 2016

Types of Recursive Methods

Assertions & Verification & Example Loop Invariants Example Exam Questions

Intro to Computational Programming in C Engineering For Kids!

TECH. Recurrence Equations vs. Recursive Procedures. Recursion and Induction. e.g. Fibonacci Function. The working of recursive procedure

Final Examination: Topics and Sample Problems

CSE 341 Section 5. Winter 2018

Note that pcall can be implemented using futures. That is, instead of. we can use

Unit #3: Recursion, Induction, and Loop Invariants

If we have a call. Now consider fastmap, a version of map that uses futures: Now look at the call. That is, instead of

Transcription:

Plan Chapter 3 Programming with Recursion 1. Examples... 3.2 2. Correctness... 3.5 3. Construction methodology... 3.13 4. Forms of recursion... 3.16 Sven-Olof Nyström/IT Dept/Uppsala University FP 3.1

3.1. Examples 3.1. Examples Factorial (revisited from Section 2.13) Program (fact.sml) fun fact n = if n < 0 then error "fact: negative argument" else if n = 0 then 1 else n fact (n 1) Useless test of the error case at each recursive call! Hence we introduce an auxiliary function, and can then use pattern matching in its declaration: fun factaux 0 = 1 factaux n = n factaux (n 1) fun fact1 n = if n < 0 then error "fact1: negative argument" else factaux n In fact1: pre-condition verification (defensive programming) In factaux: no pre-condition verification Sven-Olof Nyström/IT Dept/Uppsala University FP 3.2

3.1. Examples Exponentiation Specification function expo x n TYPE: real int real PRE: n 0 POST: x n Construction Error case: n < 0: produce an error message Base case: n = 0 : return 1 General case: n > 0 : return x n = x x n 1 = x expo x (n 1) Program (expo.sml) fun expoaux x 0 = 1.0 expoaux x n = x expoaux x (n 1) fun expo x n = if n < 0 then error "expo: negative argument" else expoaux x n Sven-Olof Nyström/IT Dept/Uppsala University FP 3.3

3.1. Examples Triangle Specification function triangle a b TYPE: int int int PRE: (none) POST: i a i b Construction Base case: a > b : return 0 General case: a b : return a i b i = a + a+1 i b i = a + triangle (a+1) b Program (triangle.sml) fun triangle a b = if a > b then 0 else a + triangle (a+1) b Sven-Olof Nyström/IT Dept/Uppsala University FP 3.4

3.2. Correctness 3.2. Correctness How do we know that a recursive program computes what we want? Lets try a very simple program. fun f n = if n = 0 then 0 else 1 + f(n-1) What does f compute? Sven-Olof Nyström/IT Dept/Uppsala University FP 3.5

3.2. Correctness Correctness (cont) What does this function compute? fun f n = if n = 0 then 0 else 1 + f(n-1) Answer: f n = n, if n>=0 Seems reasonable, but how do we prove it? Sven-Olof Nyström/IT Dept/Uppsala University FP 3.6

3.2. Correctness Proof by induction For all n >= 0, f(n) = n. Base case: n = 0. f(n) = 0 = n follows immediately. Induction step: Hypothesis: f(k) = k, for all k such that 0 <= k < n We have f(n) = 1 + f(n 1), by definition 1 + f(n 1) = 1 + (n 1), by induction hypothesis 1 + (n 1) = n, by algebraic transformations Thus f(n) = n It follows that f(n) = n, for all n >= 0. Question: What can we say about f( 1)? Sven-Olof Nyström/IT Dept/Uppsala University FP 3.7

3.2. Correctness Another example, slightly harder What does this function compute? fun g(0) = 0 g(n) = n + g(n-1) Sven-Olof Nyström/IT Dept/Uppsala University FP 3.8

3.2. Correctness Another example (cont) What does this function compute? fun g(0) = 0 g(n) = n + g(n-1) Answer: g(n) = (n n + n)/2 Proof by induction. For all n >= 0, g(n) = (n n + n)/2 Base case: n = 0. g(n) = (n n + n)/2 by definition (n n + n)/2 = (0 0 + 0)/2 = 0 Induction step Hypothesis: g(k) = (k k + k)/2, for all k such that 0 <= k < n We have g(n) = n + g(n 1), by definition = n + ((n 1) (n 1) + (n 1))/2, by induction hypothesis = n + (n n 2 n + 1 + n 1)/2, by algebraic transformations = n + (n n n)/2 n, simplification = (n n + n)/2 Thus g(n) = (n n + n)/2 It follows that g(n) = (n n + n)/2, for all n >= 0. Sven-Olof Nyström/IT Dept/Uppsala University FP 3.9

3.2. Correctness If you think these examples where too simple Exercises: Prove that the factorial given earlier produces the intended results. Prove the same for the gcd function. What do the functions below compute? Make an educated guess (try on an SML system if you like) and show by induction that your guess was correct. fun h(n) = if n = 0 then 0 else h(n-1)+2*n-1; fun m(a,b) = if a = 0 then 0 else b+m(a-1,b); Sven-Olof Nyström/IT Dept/Uppsala University FP 3.10

3.2. Correctness Correctness of functional programs Suppose we have a recursive function fun f(x) =... f(..)... and we want to show that it satisfies some property P(x, f(x)) Solution: Show that the function terminates (for all values of x that we are interested in) Assume that all recursive calls satisfy the property P(...,f(...)). Show P(x, f(x)). Then we have shown that P(x, f(x)) holds for all values of x we are interested in. (This is just an induction proof in disguise.) (By the way, showing that if an answer is returned it will be correct is also known as partial correctness.) Sven-Olof Nyström/IT Dept/Uppsala University FP 3.11

3.2. Correctness Example (factorial): fun fac(x) = if x = 0 then 1 else x*fac(x-1) Assume that fac(x) terminates for all x >= 0. Show that P(x,fac(x)) <=> fac(x) = 1 2... x holds. Assuming property holds for recursive calls... By the definition of the function fac we have fac(x) = if x = 1 then 0 else x (1 2... (x 1)) For x = 0 the property is obvious. For x <> 0 we prove the property by algebraic manipulations. Sven-Olof Nyström/IT Dept/Uppsala University FP 3.12

3.3. Construction methodology 3.3. Construction methodology Objective Construction of an SML program computing the function: given its specification S Methodology 1. Case analysis Recognize base case(s), and recursive case(s). 2. Partial correctness f(x) : D R Check that the base case returns correct result. Show that the recursive case gives correct result, assuming that all recursive calls give correct result. 3. Termination Choose a variant. A variant is typically an integer-valued expression on the input parameters together with a lower bound b so that for any recursive call, the variant is b, and for any recursive call, the variant of the recursive call is strictly less than the current call. Sven-Olof Nyström/IT Dept/Uppsala University FP 3.13

3.4. Variants in general 3.4. Variants in general Generally, a variant may be any expression whose set of possible values is some set A. For each recursive call, the variant should decrease strictly. There should be no infinite descending chain x 0 > x 1 > x 2 >... in A. Sven-Olof Nyström/IT Dept/Uppsala University FP 3.14

3.5. Tips and hints 3.5. Tips and hints Superfluous or overlapping cases Try to keep your code short and compact. Avoid redundant cases! fun fact n = if n = 0 then 1 else if n = 1 then 1 else n fact (n 1) Variants Variants are usually simple; an integer given by a parameter or the size of some input data. But watch out for the difficult cases! Sven-Olof Nyström/IT Dept/Uppsala University FP 3.15

3.6. Forms of recursion 3.6. Forms of recursion Up to now: One recursive call Some variant is decremented by one That is: simple recursion (construction process by simple induction) Forms of recursion Simple recursion Complete recursion Multiple recursion Mutual recursion Nested recursion Recursion on a generalised problem Sven-Olof Nyström/IT Dept/Uppsala University FP 3.16

3.6. Forms of recursion Complete recursion Example 1: integer division (quotient and remainder) Specification function intdiv 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 Variant: a Error case: a < 0 or b 0 : produce an error message Base case: a < b : since a = 0 b + a, return (0,a) This covers more than the minimal value of a (namely 0)! General case: a b : since a = q b + r iff (a b) = (q 1) b + r, the call intdiv (a b) b will give q 1 and r Sven-Olof Nyström/IT Dept/Uppsala University FP 3.17

3.6. Forms of recursion Program (intdiv.sml) fun intdivaux a b = if a < b then (0,a) else let val (q1,r1) = intdivaux (a b) b in (q1+1,r1) end fun intdiv a b = if a < 0 orelse b <= 0 then error "intdiv: invalid argument" else intdivaux a b Necessity of the induction hypothesis not only for a 1, but actually for all values less than a: complete induction! Sven-Olof Nyström/IT Dept/Uppsala University FP 3.18

3.6. Forms of recursion Example 2: exponentiation (revisited from Section 3.1) Specification function fastexpo x n TYPE: real int real PRE: n 0 POST: x n Construction Variant: n Error case: n < 0: produce an error message Base case: n = 0 : return 1 General case: n > 0 : if n is even, then return x n div 2 x n div 2 otherwise, return x x n div 2 x n div 2 Sven-Olof Nyström/IT Dept/Uppsala University FP 3.19

3.6. Forms of recursion Program (expo.sml) fun fastexpo x n = let fun fastexpoaux x 0 = 1.0 fastexpoaux x n = let val r = fastexpoaux x (n div 2) in if even n then r r else x r r end in end if n < 0 then error "fastexpo: negative argument" else fastexpoaux x n Complete recursion, but the size of the input is divided by 2 each time! Complexity Let C(n) be the number of multiplications made (in the worst case) by fastexpo: C(0) = 0 C(n) = C(n div 2) + 2 for n > 0 One can show that C(n) = O(log n) Sven-Olof Nyström/IT Dept/Uppsala University FP 3.20

3.6. Forms of recursion Multiple recursion Example: the Fibonacci numbers Definition fib (0) = 1 fib (1) = 1 fib (n) = fib (n 1) + fib (n 2) for n > 1 Specification function fib n TYPE: int int PRE: n 0 POST: fib (n) Program (fib.sml) Variant: n fun fib 0 = 1 fib 1 = 1 fib n = fib (n 1) + fib (n 2) Double recursion Inefficient: multiple recomputations of the same values! Sven-Olof Nyström/IT Dept/Uppsala University FP 3.21

3.6. Forms of recursion Mutual recursion Example: recognising even integers and odd integers Specification function even n TYPE: int bool PRE: n 0 POST: true if n is even false otherwise function odd n TYPE: int bool PRE: n 0 POST: true if n is odd false otherwise Program (even.sml) Variant: n fun even 0 = true even n = odd (n 1) and odd 0 = false odd n = even (n 1) Simultaneous declaration of the functions Global correctness reasoning Sven-Olof Nyström/IT Dept/Uppsala University FP 3.22

3.6. Forms of recursion Nested recursion and lexicographic order Example 1: the Ackermann function Definition For m, n 0: acker (0,m) = m+1 acker (n,0) = acker (n 1, 1) for n > 0 acker (n,m) = acker (n 1, acker (n, m 1)) for n, m > 0 Program (acker.sml) Variant: the pair (n,m) fun acker 0 m = m+1 acker n 0 = acker (n 1) 1 acker n m = acker (n 1) (acker n (m 1)) where (n, m ) < lex (n, m) iff n < n or (n = n and m < m) This is called a lexicographic order The function acker always terminates It can be shown that Ackermann s function can not be expressed as a primitive-recursive function. Sven-Olof Nyström/IT Dept/Uppsala University FP 3.23

3.6. Forms of recursion Example 2: Graham s number, the largest number Definition Operator n (invented by Donald Knuth): a 1 b = a b a n b = a n 1 (b n 1 b) for n > 1 Program (graham.sml) Variant: n fun opknuth 1 a b = Math.pow (a,b) opknuth n a b = opknuth (n 1) a (opknuth (n 1) b b) - opknuth 2 3.0 3.0 ; val it = 7.62559748499E12 : real - opknuth 3 3.0 3.0 ;! Uncaught exception: Overflow Graham s number is opknuth 63 3.0 3.0 It is in the Guiness Book of Records! Sven-Olof Nyström/IT Dept/Uppsala University FP 3.24

3.6. Forms of recursion Recursion on a generalised problem Example: recognising prime numbers Specification function prime n TYPE: int bool PRE: n > 0 POST: true if n is a prime number false otherwise Construction It is impossible to determine whether n is prime via the reply to the question is n 1 prime? It seems impossible to directly construct a recursive program We thus need to find another function: that is more general than prime, in the sense that prime is a particular case of this function for which a recursive program can be constructed Sven-Olof Nyström/IT Dept/Uppsala University FP 3.25

3.6. Forms of recursion Specification of the generalised function function divisors n low up TYPE: int int int bool PRE: n, low, up 1 POST: true if n has no divisors in {low,..., up} false otherwise Construction of a program for the generalised function Variant: up low + 1, which is the size of {low,..., up} Base case: low > up : return true because the set {low,..., up} is empty General case: low up : if n is divisible by low, then return false otherwise, return whether n has a divisor in {low+1,..., up} Construction of a program for the original function The function prime is a particular case of the function divisors, namely when low is 2 and up is n 1 One can also take up as n, and this is more efficient Sven-Olof Nyström/IT Dept/Uppsala University FP 3.26

3.6. Forms of recursion Program (prime.sml) fun divisors n low up = low > up orelse (n mod low) <> 0 andalso divisors n (low+1) up fun prime n = if n <= 0 then error "prime: non positive argument" else if n = 1 then false else divisors n 2 (floor (Math.sqrt (real n))) The function divisors may be useful for other problems The discovery of divisors requires imagination and creativity There are some standard methods of generalising problems: let the recursive function take more 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 tupling generalisation: replace a parameter by a list of parameters of the same type Sometimes the only way to solve the problem at hand is to consider a more general problem. Often, a generalized problem may be more efficient regarding time and/or space consumption. Exercises: 1. Which standard method of generalization did we apply in the implementation of the primes function? 2. (Harder) Implement a function that computes fib(n) in time proportional to n. Hint: You will need to define a function that solves a more general problem. Sven-Olof Nyström/IT Dept/Uppsala University FP 3.27