PowerPoint Presentation - Distributed Systems Lecture 11

advertisement
1
Recursion
Jeff Parker, Merrimack College
CS2 @ Dennison, June 2008
In order to understand recursion you
just need to understand recursion.
2
Outline
Recursion is important
We use it to describe things (BNF)
Many algorithms are best expressed recursively
Our choice is not if we should teach it, but how to teach it
Recursion is hard
Our students don't understand it
Our students fear it
This talk hopes to provide
Review of the literature
More ideas than you can possibly use, and
A framework to work within
3
How to teach it
There are two theories on how to teach it: Students should
Have a strong model of how it works, or
Have a template for how to use it, without worrying so
much about how it works [Long, Weide, Bucci]
These are not as contradictory as they seem
Understanding how it works well enough to predict what
a new example does is important
Understanding how it works does not help us solve new
problems
We need both skills. But we need more…
4
Framework for teaching
Motivation
As with any new notion, the student must have a reason to
master the new idea.
Need a problem they cannot solve without recursion
Mental model of recursion
Must be strong enough to allow student to test alternatives.
Understanding of how to apply recursion
The mental model helps us simulate action of function.
Does not help us write the function in the first place.
5
Motivation
We want examples that grab the students
We don't have to explain in full detail
- that comes later
Look for examples in the following areas
Images
Language
Text: pyramids, reverse – ASCII "graphics"
Games and Puzzles
Avoid fib() and factorial()
Prefer power(base, exp)
As well as problems that recursion can help us
solve, we explore the richness of recursion
6
Images
Images are excellent at capturing the idea
Some of the images are recursive by nature
Some are easy to describe recursively
Introducing APIs needed to write examples is barrier
If we are using these as motivation this isn't an issue
Some images are distracting
As much as we like them, they confuse our students
7
Dan Gries' Fractal Maker
A system that lets students play with different fractal images
Can select the depth of recursive calls
Has a nice library of examples
http://www.dangries.com/Flash/FractalMaker.html
8
Dolls
9
Images
10
Recursion in Language
Noam Chomsky believes that the ability to recursively extend a sentence
is hardwired.
This is the man all tattered and torn,
That kissed the maiden all forlorn,
That milked the cow with the crumpled horn,
That tossed the dog, That worried the cat,
That killed the rat, That ate the malt
That lay in the house that Jack built.
Khad Gadya
One little goat that Father bought for two zuzim.
Daniel Everett has proposed the Pirahã language as a counter-example.
11
Recursion in Language
An interesting exercise in inductive reasoning is to discuss the statement
A King is a son of a King
Is this true? Why or why not?
George I ascended after James II was deposed.
Does this prove that Prince Charles can never take the throne?
If we assume it is true, what else can we say about Kings?
12
Other Motivating Examples
13
Student Mental Models
[Kahney] analyzed student mental models
Looping model – Recursion as a form of iteration
Step Model – just follow the program one step at a time
Return Value Model – Assumes each call returns at once
Models in which Return returns to the main…
Magic Model – No Clue
Copies Model – Distinct invocations of a routine (the
only correct model)
Each Slugo is different
Since then, other models have been suggested.
Part of our task is to render other models untenable
14
Copies Model
[George] argues that to teach Copies model, we must
Show active flow of control (from caller to callee)
Show passive flow of control (callee returns to caller)
Understand the base case
We can explain all this with linear recursion (single call)
Pure Tail Recursion does not have observable passive flow
Embedded Recursion may
You can observe a lot just by watching
- Yogi Berra
Print a String
void print(string str)
{
if (str.length() > 0)
{
char ch = str.at(0);
string tail = str.substr(1, str.length());
print(tail);
cout << ch;
}
}
[Ford] Call on students to act out roles
Each student has a different copy of this page
I think it is important to make tail explicit, rather than a function call
if (str.length() > 0) { ...
print(str.substr(1, str.length()));
15
str
ch
tail
print("STOP");
16
Reverse a String
To focus on passive flow, assemble work
In this function, we build a string
string reverse(string str)
{
if (str.length() == 0)
return str;
else
{
char ch = str.at(0);
string tail = str.substr(1, str.length());
return tail + ch;
}
}
str
ch
tail
reverse("STOP");
17
Teaching Models
[Wu, Dale, and Bethel] identify 5 teaching models
Three are concrete, two abstract
Russian Dolls - smaller versions of the original (recursive call) and a doll
that you cannot open (base case)
Process Tracing – Use call tree [Kruse] or activation trace [Haynes]
Stack Simulation – Show the underlying computer architecture used
Mathematical Induction – Mathematical examples and Proof by Induction
Structure template – Sample solutions and a template that they can fill in
They believe that different students will prefer different approaches
18
Writing Recursive Routines
The third leg of the stool is to write recursive routines
When we present a recursive definition of the Factorial function,
we have skipped the step that students find most difficult
When we teach functions, we teach students to understand what
the client needs, and to write a provider to implement it.
Recursive routines are both client and provider
[Long, Weide, Bucci]: Apply this to your problem of choice
19
Recursion in Text
CS1 Students were given problem to reverse the elements of DNS name
They had struggled to write an iterative solution
w
w
w
e
d
u
.
.
d
e
n
d
e
n
i
s
i
s
o
o
n
n
.
.
e
d
u
w
w
w
20
Reverse a string w/ three words
string reverse3word(string str)
{
string::size_type pos = str.find(‘.’);
string word = str.substr(pos+1, str.length();
return reverse2word(word) + “.” + str.substr(0, pos);
}
Of course, this does not work if there are no dots.
Bullet-proof this with a check that pos is not negative
w
w
w
.
d
e
n
i
s
o
n
.
e
d
u
21
Reverse a string
string reverse3word(string str)
{
string::size_type pos = str.find(‘.’);
if (string::npos == pos)
return str;
else {
string word = str.substr(pos+1, str.length();
return reverse2word(word) + “.” + str.substr(0, pos);
}
}
string reverse2word(string str)
{
string::size_type pos = str.find(‘.’);
if (string::npos == pos)
return str;
else {
string word = str.substr(pos+1, str.length();
return reverse1word(word) + “.” + str.substr(0, pos);
}
}
string reverse1word(string str)
{
return str;
}
22
Visualizing the Call Stack
We have two copies
of Pow3 on the stack
This one has a value
of n = 6
The arrow in bottom
panel shows where
the program is
running
The debugger shows the stack, for those that understand it
23
EROSI
While the debugger has all the information, we do not see the two calls to
power as distinct objects
[George] proposed the EROSI (Explicit Representer of Subprogram
Invocations) system that shows each invocation as a distinct object
int main()
{
p = power(2, 13)
power(2, 13)
{
…
temp = power(2, 13/2);
…
return temp;
power(2, 6)
{
…
temp = power(2, 6/2);
…
return temp;
Tracing Calls: Filling
Consider the task of filling a region
25
Call Tracking
Call trees are the gold standard [Kruse]
Creating them requires solid understanding
// Fill Boolean array image at point (row, col)
void fill(bool image[MAX][MAX], int row, int col)
{
// Is the fill point within the graph?
if ((row < 0) || (row >= MAX) || (col < 0) || (col >= MAX))
return;
// Is the graph empty at the fill point?
if (image[row][col])
return;
// Turn on the point
image[row][col] = true;
// Try to fill in the surrounding area
fill(image, row-1, col, level + 1);
fill(image, row+1, col, level + 1);
fill(image, row, col-1, level + 1);
fill(image, row, col+1, level + 1);
}
26
Mechanical Call Tracking
Simplest mechanical aid is to print info as we enter function
Adding indenting to show stack depth [Haynes]
void fill(bool image[MAX][MAX], int row, int col, int level)
{
cout << indent(level) << "fill(" << row << ", " << col << ")\n";
...
// Fill in the surrounding area
fill(image, row-1, col, level + 1);
fill(image, row+1, col, level + 1);
fill(image, row, col-1, level + 1);
fill(image, row, col+1, level + 1);
}
fill(4, 4)
fill(3, 4)
fill(2, 4)
fill(1, 4)
fill(3, 4)
fill(2, 3)
fill(2, 5)
fill(1, 5)
fill(3, 5)
27
Mechanical Call Tracking
Here we track which call (first, second, third…) filled each cell
void fill(bool image[MAX][MAX], int row, int col, int & cnt, int count[MAX][MAX])
{
// Is the fill point within the graph?
if ((row < 0) || (row >= MAX) || (col < 0) || (col >= MAX))
return;
// Is the graph empty at the fill point?
if (image[row][col])
return;
// Turn on the point
image[row][col] = true;
count[row][col] = ++cnt;
// Try to fill in the surrounding area
fill(image, row-1, col, cnt, count);
fill(image, row+1, col, cnt, count);
fill(image, row, col-1, cnt, count);
fill(image, row, col+1, cnt, count);
}
0
0
0
0
0
0
0
0
0
0
0 0 0 0 0
0 0 X X X
0 X X 3 4
X X 15 2 5
X 26 16 1 X
X 25 17 23 X
0 X 18 22 X
X 20 19 21 24
0 X X X X
0 0 0 0 0
0
X
X
6
7
8
9
X
X
0
0
0
X
13
12
11
10
14
X
0
0
0
0
X
X
X
X
X
X
0
0
0
0
0
0
0
0
0
0
0
28
Dramatizations
Ben-Ari suggests that we dramatize recursion
He gives 3 examples. Each emphasizes the passive flow.
Open a present (Improvement on nested Matryoshka Dolls)
The receiver thanks the presenter to show passive flow
Build a chain of N links by adding a link on passive path
Count the nuts in a Chocolate Bar: assemble count
29
Summary
Motivation
Give students a reason to master a new idea.
Mental model of the process
Provide a mental model that they can use
Reinforce with call tracing, call trees, etc.
Understanding of how to apply recursion
Use functional decomposition to break problem down
Templates may help: should not be straight-jacket
30
Selected Sources
[Ford] A framework for teaching Recursion, SIGCSE Bulletin, 1982.
[Kahney] Modelling novice programmer behaviour. In: New horizons in
educational computing,1984.
[Haynes] Explaining Recursion to the Unsophisticated, SIGCSE Bulletin,
September 1995
[Ben-Ari] Recursion: From Drama to Program, Journal of Computer
Science Education, 11(3), 1997
[Wu, Dale, Bethel] Conceptual Models and Cognitive Learning Styles.
SIGCSE 98
[Long, Weide, Bucci] ClientView First: An Exodus From ImplementationBiased Teaching, SIGCSE 1999
[George] EROSI – Visualizing Recursion and Discovering New Errors,
SIGCSE 2000
Download