Logic Programming Lecture 3: Recursion, lists, and data structures.
Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this...
Transcript of Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this...
![Page 1: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/1.jpg)
Lecture 17: Recursion
(Re‐introduction of this topic first discussed over 3 weeks ago!)
(Sections 5.8‐5.10)
CS 1110Introduction to Computing Using Python
[E. Andersen, A. Bracy, D. Fan, D. Gries, L. Lee, S. Marschner, C. Van Loan, W. White]
http://www.cs.cornell.edu/courses/cs1110/2020sp
![Page 2: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/2.jpg)
Recursion
Recursive Function: A function that calls itself
An example in mathematics: factorial• Non-recursive definition:
n! = n × n-1 × … × 2 × 1
• Recursive definition:n! = n (n-1)!0! = 1
3
(n-1)!
![Page 3: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/3.jpg)
Recursion
Recursive Function: A function that calls itself
Two parts to every recursive function:1. A simple case: can be solved easily2. A complex case: can be made simpler (and simpler,
and simpler… until it looks like the simple case)
4
![Page 4: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/4.jpg)
5
Russian Dolls!
![Page 5: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/5.jpg)
7
Think about opening a set of Russian dolls as a “problem.” Which is the simpler case,
the case where the doll has a seam and another doll inside of it, or
the case where the doll has no seam and no doll inside of it?
![Page 6: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/6.jpg)
8
Russian Dolls!
import russian
id1
name
hasSeam
Doll
innerDoll
![Page 7: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/7.jpg)
9
Russian Dolls!
import russiand1 = russian.Doll("Dmitry", None)d2 = russian.Doll("Catherine", d1)
id1
name
hasSeam
"Dmitry"
False
None
Doll
innerDoll
id1d1
Heap Space Global Space
id2
name
hasSeam
"Catherine"
True
id1
Doll
innerDoll
id2d2"Dmitry"
"Catherine"
![Page 8: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/8.jpg)
def open_doll(d):"""Input: a Russian DollOpens the Russian Doll d """print("My name is "+ d.name)if d.hasSeam:
# open inner dollopen_doll2(d.innerDoll)
else:print("That's it!")
idx
namehasSeam
Doll
innerDoll
![Page 9: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/9.jpg)
def open_doll2(d):"""Input: a Russian DollOpens the Russian Doll d """print("My name is "+ d.name)if d.hasSeam:
# open inner dollopen_doll3(d.innerDoll)
else:print("That's it!")
idx
namehasSeam
Doll
innerDoll
![Page 10: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/10.jpg)
def open_doll3(d):"""Input: a Russian DollOpens the Russian Doll d """print("My name is "+ d.name)if d.hasSeam:
# open inner dollopen_doll4(d.innerDoll)
else:print("That's it!")
idx
namehasSeam
Doll
innerDoll
![Page 11: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/11.jpg)
def open_doll(d):"""Input: a Russian DollOpens the Russian Doll d """print("My name is "+ d.name)if d.hasSeam:
inner = d.innerDollopen_doll(inner)
else:print("That's it!")
idx
namehasSeam
Doll
innerDoll
![Page 12: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/12.jpg)
Play with the code
• Download modules russian.py, playWithDolls.py• Read playWithDolls.py; then run it as a script.• Modify last statement and run script again: open_doll(d3)
• Modify last statement again and run script again : open_doll(d1)
• Do you understand the result? Visit virtual office/consulting hours if you have any questions.
15
![Page 13: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/13.jpg)
[Start next video:more examples]
16
![Page 14: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/14.jpg)
Recursion: Examples
• Russian Dolls• Blast Off!• Factorial• Count number of ‘e’s• Deblank – removing spaces from a string
17
![Page 15: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/15.jpg)
blast_off(5) # must be a non-negative int
54321BLAST OFF!
blast_off(0)BLAST OFF!
18
Blast Off!
![Page 16: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/16.jpg)
blast_off(5) # must be a non-negative int
54321BLAST OFF!
blast_off(0)BLAST OFF!
20
Blast Off!
What is the simple case that can be solved easily?
• positive n > 1 • n is 1• n is 0
![Page 17: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/17.jpg)
def blast_off(n):"""Input: a non-negative intCounts down from n to Blast-Off! """if (n == 0):
print("BLAST OFF!")else:
print(n)blast_off(n-1)
21
Blast Off!
![Page 18: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/18.jpg)
A Mathematical Example: Factorial
• Non-recursive definition:n! = n × n-1 × … × 2 × 1
= n (n-1 × … × 2 × 1)
• Recursive definition:n! = n (n-1)!0! = 1
Recursion 22
for n > 0 Recursive caseBase case
What happens if there is no base case?
![Page 19: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/19.jpg)
Factorial as a Recursive Function
def factorial(n):"""Returns: factorial of n.Pre: n ≥ 0 an int"""if n == 0:
return 1
return n*factorial(n-1)
• n! = n (n-1)!• 0! = 1
Recursion 23
What happens if there is no base case?
Recursive case
Base case(s)
![Page 20: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/20.jpg)
Recursion vs Iteration
• Recursion is provably equivalent to iteration Iteration includes for-loop and while-loop (later) Anything can do in one, can do in the other
• But some things are easier with recursion And some things are easier with iteration
• Will not teach you when to choose recursion That’s for upper level courses
• We just want you to understand the technique24
![Page 21: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/21.jpg)
[Start next video:divide & conquer]
25
![Page 22: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/22.jpg)
Recursion is great for Divide and Conquer
Goal: Solve problem P on a piece of data
28
dataIdea: Split data into two parts and solve problem
data 1 data 2
Solve Problem P Solve Problem P
Combine Answer!
![Page 23: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/23.jpg)
Divide and Conquer Example
Count the number of 'e's in a string:
29
p e nn e
Two 'e's
p e nn e
One 'e' One 'e'
![Page 24: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/24.jpg)
Divide and Conquer Example
Count the number of 'e's in a string:
30
p e nn e
Two 'e's
p e nn e
Zero 'e's Two 'e's
![Page 25: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/25.jpg)
Divide and Conquer
Goal: Solve really big problem PIdea: Split into simpler problems, solve, combine
3 Steps:1. Decide what to do for simple cases2. Decide how to break up the task3. Decide how to combine your work
32
![Page 26: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/26.jpg)
Three Steps for Divide and Conquer
1. Decide what to do on “small” data Some data cannot be broken up Have to compute this answer directly
2. Decide how to break up your data Both “halves” should be smaller than whole Often no wrong way to do this (next lecture)
3. Decide how to combine your answers Assume the smaller answers are correct Combining them should give bigger answer
33
![Page 27: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/27.jpg)
Divide and Conquer Example
def num_es(s):"""Returns: # of 'e's in s"""# 1. Handle small dataif s == '':
return 0elif len(s) == 1:
return 1 if s[0] == 'e' else 0
# 2. Break into two partsleft = num_es(s[0])right = num_es(s[1:])
# 3. Combine the resultreturn left+right
35
![Page 28: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/28.jpg)
Divide and Conquer Example
def num_es(s):"""Returns: # of 'e's in s"""# 1. Handle small dataif s == '':
return 0elif len(s) == 1:
return 1 if s[0] == 'e' else 0
# 2. Break into two partsleft = num_es(s[0])right = num_es(s[1:])
# 3. Combine the resultreturn left+right
36
![Page 29: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/29.jpg)
Divide and Conquer Example
def num_es(s):"""Returns: # of 'e's in s"""# 1. Handle small dataif s == '':
return 0elif len(s) == 1:
return 1 if s[0] == 'e' else 0
# 2. Break into two partsleft = num_es(s[0])right = num_es(s[1:])
# 3. Combine the resultreturn left+right
37
“Short-cut” forif s[0] == 'e’:
return 1else:
return 0
![Page 30: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/30.jpg)
Divide and Conquer Example
def num_es(s):"""Returns: # of 'e's in s"""# 1. Handle small dataif s == '':
return 0elif len(s) == 1:
return 1 if s[0] == 'e' else 0
# 2. Break into two partsleft = num_es(s[0])right = num_es(s[1:])
# 3. Combine the resultreturn left+right
38
p e nn e
0 2
s[0] s[1:]
![Page 31: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/31.jpg)
Divide and Conquer Example
def num_es(s):"""Returns: # of 'e's in s"""# 1. Handle small dataif s == '':
return 0elif len(s) == 1:
return 1 if s[0] == 'e' else 0
# 2. Break into two partsleft = num_es(s[0])right = num_es(s[1:])
# 3. Combine the resultreturn left+right
39
p e nn e
0 2+
s[0] s[1:]
![Page 32: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/32.jpg)
Divide and Conquer Example
def num_es(s):"""Returns: # of 'e's in s"""# 1. Handle small dataif s == '':
return 0elif len(s) == 1:
return 1 if s[0] == 'e' else 0
# 2. Break into two partsleft = num_es(s[0])right = num_es(s[1:])
# 3. Combine the resultreturn left+right
40
Base Case
RecursiveCase
![Page 33: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/33.jpg)
Exercise: Remove Blanks from a String
def deblank(s):"""Returns: s but with its blanks removed"""
1. Decide what to do on “small” data If it is the empty string, nothing to do
if s == '':return s
If it is a single character, delete it if a blankif s == ' ': # There is a space here
return '' # Empty stringelse:
return s41
![Page 34: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/34.jpg)
Exercise: Remove Blanks from a String
def deblank(s):"""Returns: s but with its blanks removed"""
2. Decide how to break it upleft = deblank(s[0]) # A string with no blanksright = deblank(s[1:]) # A string with no blanks
3. Decide how to combine the answersreturn left+right # String concatenation
42
![Page 35: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/35.jpg)
Putting it All Together
def deblank(s):"""Returns: s w/o blanks"""if s == '':
return selif len(s) == 1:
return '' if s[0] == ' ' else s
left = deblank(s[0])right = deblank(s[1:])
return left+right
43
Handle small data
Break up the data
Combine answers
![Page 36: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/36.jpg)
Putting it All Together
def deblank(s):"""Returns: s w/o blanks"""if s == '':
return selif len(s) == 1:
return '' if s[0] == ' ' else s
left = deblank(s[0])right = deblank(s[1:])
return left+right
44
Base Case
RecursiveCase
![Page 37: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/37.jpg)
Following the Recursion
a b cdeblank
45
deblank a b cdeblank
stop (base case)adeblank
stop (base case)
b cdeblank
…You really, really, really want to visualize a call of deblank using Python Tutor. Pay attention to the recursive calls (call frames opening up), the completion of a call (sending the result to the call frame “above”), and the resulting accumulation of the answer.
![Page 38: Lecture 17 - Cornell University · 2020-04-09 · Lecture 17: Recursion (Re‐introduction of this topic first discussed over 3 weeks ago!) (Sections 5.8‐5.10) CS 1110 Introduction](https://reader034.fdocuments.in/reader034/viewer/2022043020/5f3c084ee9dac96b07607636/html5/thumbnails/38.jpg)
Post-lecture exercise
• Visualize a call of deblank using Python Tutor• Code in file deblank.py• Pay attention to the recursive calls (call frames opening up), the completion of a call (sending the result to the call frame “above”), and the resulting accumulation of the answer.
• Do this exercise before next lecture. Really!
59