Advanced recursion design by contract data abstraction
Download
1 / 86

Advanced Recursion Design by Contract Data Abstraction - PowerPoint PPT Presentation


  • 194 Views
  • Uploaded on

Lecture 7. Advanced Recursion Design by Contract Data Abstraction. Advanced Recursion. Recursive Function Example: Factorial. Problem: calculate n! (n factorial) n! = 1 if n = 0 n! = 1 * 2 * 3 *...* n if n > 0 Recursively: if n = 0 , then n! = 1

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Advanced Recursion Design by Contract Data Abstraction' - vilmos


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Advanced recursion design by contract data abstraction l.jpg

Lecture 7

Advanced RecursionDesign by ContractData Abstraction



Recursive function example factorial l.jpg
Recursive Function Example: Factorial

Problem: calculate n! (n factorial)

n! = 1 if n = 0

n! = 1 * 2 * 3 *...* n if n > 0

Recursively:

if n = 0, then n! = 1

if n > 0, then n! = n * (n-1)!


Solving recursive problems l.jpg
Solving Recursive Problems

  • See recursive solutions as two sections:

    • Current

    • Rest

      N! = N * (N-1)!

      7! = 7 * 6!

      7! = 7 * (6 * 5 * 4 * 3 * 2 * 1 * 1)


Factorial function l.jpg
Factorial Function

function Factorial returnsa Num

(n isoftype in Num)

// Calculates n factorial, n!

// Precondition: n is a non-negative

// integer

if (n = 0) then

Factorial returns 1

else

Factorial returns n * Factorial(n-1)

endif

endfunction //Factorial


Slide6 l.jpg

if (0 = 0)

then Fact returns 1

else

Fact returns 1

endif

endfunction //Fact

if (1 = 0)

then Fact returns 1

else

Fact returns 1 * Fact(0)

endif

endfunction //Fact

if (2 = 0)

then Fact returns 1

else

Fact returns 2 * Fact(1)

endif

endfunction //Fact

if (3 = 0)

then Fact returns 1

else

Fact returns 3 * Fact(2)

endif

endfunction //Fact

algorithm Test

ans <- Fact(3)

endalgorithm


Tracing details l.jpg

1. Actual parameters stored on the stack

5. Return value and release stack frame

3. Create a new Stack Frame

4. Unfinished Business

2. Recursive call to Fact

Tracing Details

function Fact returnsa Num (2)

if (2 = 0)

then Fact returns 1

else

Fact returns 2 * Fact(1)

endif

endfunction //Fact


Activation stack for factorial l.jpg
Activation Stack for Factorial

Call the function: answer <- Fact(5)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial9 l.jpg
Activation Stack for Factorial

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial10 l.jpg
Activation Stack for Factorial

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial11 l.jpg
Activation Stack for Factorial

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial12 l.jpg
Activation Stack for Factorial

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial13 l.jpg
Activation Stack for Factorial

Fact. 5th: N=1, Unfinished: 1*Fact(0)

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial14 l.jpg
Activation Stack for Factorial

Fact. 6th: N=0, Finished: returns 1

Fact. 5th: N=1, Unfinished: 1*Fact(0)

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial15 l.jpg
Activation Stack for Factorial

Fact. 5th: N=1, Finished: returns 1*1

Fact. 4th: N=2, Unfinished: 2*Fact(1)

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial16 l.jpg
Activation Stack for Factorial

Fact. 4th: N=2, Finished: returns 2*1

Fact. 3rd: N=3, Unfinished: 3*Fact(2)

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial17 l.jpg
Activation Stack for Factorial

Fact. 3rd: N=3, Finished: returns 3*2

Fact. 2nd: N=4, Unfinished: 4*Fact(3)

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial18 l.jpg
Activation Stack for Factorial

Fact. 2nd: N=4, Finished: returns 4*6

Fact. 1st: N=5, Unfinished: 5*Fact(4)

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial19 l.jpg
Activation Stack for Factorial

Fact. 1st: N=5, Finished: returns 5*24

Main Algorithm: Unfinished: answer <- Fact (5)


Activation stack for factorial20 l.jpg
Activation Stack for Factorial

Main Algorithm: Finished: answer <- 120


Exponentiation l.jpg

LB

Exponentiation

baseexponent

e.g. 53

Could be written as a function

Power(base, exp)


Can we write it recursively l.jpg

LB

Can we write it recursively?

be = b * b(e-1)

What’s the limiting case?

When e = 0 we have b0 which always equals?

1


Another recursive function l.jpg
Another Recursive Function

function Power returnsa Num

(base, exp isoftype in Num)

// Computes the value of BaseExp

// Pre: exp is a non-negative integer

if (exp = 0) then

Power returns 1

else

Power returns base * Power(base, exp-1)

endif

endfunction //Power


Activations stack example l.jpg

Power base = 3 exp = 0 Finished:1

1

Power base = 3 exp = 1 3 *Power(3,0)

3

Power base = 3 exp = 2 3 *Power(3,1)

9

Power base = 3 exp = 3 3 *Power(3,2)

27

Power base = 3 exp = 4 3 *Power(3,3)

81

Algo: total <- Power(3,4)

Function Power returnsa Num (base, exp isoftype in Num)

//Computes the value of BaseExp

//Preconditions: exp is a non-negative integer

if(exp = 0 ) then

Power returns 1

else

Power returns

(base *

Power(base, exp – 1))

endif

endfunction //Power

Activations Stack Example

1

3

9

27

Total <- 81


Bunnies l.jpg

LB

Bunnies?

  • The Time: 13th Century

  • The Place: Italy

  • The Man: Fibonacci

  • The Problem: We start with a pair of newborn rabbits. At the end of the 2nd month, and each month thereafter the female gives birth to a new pair of rabbits: one male and one female. The babies mature at the same rate as the parents and begin to produce offspring on the same schedule. So how many rabbits do we have at the end of one year?



A more complex recursive function l.jpg
A More Complex Recursive Function

Fibonacci Number Sequence

if n = 1, then Fib(n) =1

if n = 2, then Fib(n) = 1

if n > 2, then Fib(n) = Fib(n-2) + Fib(n-1)

Numbers in the series:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...


Fibonacci sequence function l.jpg
Fibonacci Sequence Function

function Fib returnsa Num (n iot in Num)

// Calculates the nth Fibonacci number

// Precondition: N is a positive integer

if ((n = 1) OR (n = 2)) then

Fib returns 1

else

Fib returnsFib(n-2) + Fib(n-1)

endif

endfunction //Fibonacci


Tracing with multiple recursive calls l.jpg
Tracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls30 l.jpg
Tracing with Multiple Recursive Calls

Fib(5): Fib returns Fib(3) + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls31 l.jpg
Tracing with Multiple Recursive Calls

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(5): Fib returns Fib(3) + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls32 l.jpg
Tracing with Multiple Recursive Calls

Fib(1): Fib returns 1

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(5): Fib returns Fib(3) + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls33 l.jpg
Tracing with Multiple Recursive Calls

Fib(3): Fib returns 1 + Fib(2)

Fib(5): Fib returns Fib(3) + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls34 l.jpg
Tracing with Multiple Recursive Calls

Fib(2): Fib returns 1

Fib(3): Fib returns 1 + Fib(2)

Fib(5): Fib returns Fib(3) + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls35 l.jpg
Tracing with Multiple Recursive Calls

Fib(3): Fib returns 1 + 1

Fib(5): Fib returns Fib(3) + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls36 l.jpg
Tracing with Multiple Recursive Calls

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls37 l.jpg
Tracing with Multiple Recursive Calls

Fib(4): Fib returns Fib(2) + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls38 l.jpg
Tracing with Multiple Recursive Calls

Fib(2): Fib returns 1

Fib(4): Fib returns Fib(2) + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls39 l.jpg
Tracing with Multiple Recursive Calls

Fib(4): Fib returns 1 + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls40 l.jpg
Tracing with Multiple Recursive Calls

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(4): Fib returns 1 + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls41 l.jpg
Tracing with Multiple Recursive Calls

Fib(1): Fib returns 1

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(4): Fib returns 1 + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls42 l.jpg
Tracing with Multiple Recursive Calls

Fib(3): Fib returns 1 + Fib(2)

Fib(4): Fib returns 1 + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls43 l.jpg
Tracing with Multiple Recursive Calls

Fib(2): Fib returns 1

Fib(3): Fib returns 1 + Fib(2)

Fib(4): Fib returns 1 + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls44 l.jpg
Tracing with Multiple Recursive Calls

Fib(3): Fib returns 1 + 1

Fib(4): Fib returns 1 + Fib(3)

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls45 l.jpg
Tracing with Multiple Recursive Calls

Fib(4): Fib returns 1 + 2

Fib(5): Fib returns 2 + Fib(4)

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls46 l.jpg
Tracing with Multiple Recursive Calls

Fib(5): Fib returns 2 + 3

Main Algorithm: answer <- Fib(5)


Tracing with multiple recursive calls47 l.jpg
Tracing with Multiple Recursive Calls

Main Algorithm: answer <- 5


Mutual recursion l.jpg
Mutual Recursion

Recursion doesn’t always occur because a routine calls itself...

Mutual Recursion occurs when two routines call each other.

A

B

A

B


Mutual recursion example l.jpg
Mutual Recursion Example

Problem: Determine whether a number, N, is odd or even.

  • If N is equal to 0, then n is even

  • N is odd if N-1 is even


Example implementation l.jpg
Example Implementation

function Odd returnsa Boolean (n iot in Num)

if (n = 0) then

Odd returns FALSE

else

Odd returns Even (n - 1)

endif

endfunction //Odd

function Even returnsa Boolean (n iot in Num)

if (n = 0) then

Even returns TRUE

else

Even returns Odd (n - 1)

endif

endfunction //Even


Building recursive modules l.jpg
Building Recursive Modules

  • Decide on the terminating condition

  • Decide the final actions when you terminate

    • There may be none

    • If you are computing something, this usually starts a “ripple” of returned data

  • Decide how to take a step closer to terminating

    • think about how to make your original, complex problem simpler

  • Decide how to call a “clone” of this module

  • Decide what work to do at this step in recursion




Slide54 l.jpg

An Example Module

  • function Fibonacci returnsa Num(n isoftype in num)

  • // Returns Nth fibonacci number

  • if ((n=0) OR (n=1)) then

  • Fibonacci returns 1

  • else

  • Fibonacci returns Fibonacci(n-1) + Fibonacci(n-2)

  • endif

  • endfunction // Fibonacci


Slide55 l.jpg

Correctness

What if we call it via:

some_var <- Fibonacci(-1)

or

some_var <- Fibonacci(4.3)

The module will never reach its terminating condition and willnever end!


Slide56 l.jpg

A First Try at a Correction

  • function Fibonacci returnsa num (n iot in num)

  • // Returns Nth fibonacci number

  • // Ensure n is a non-negative integer

  • if ((n < 0) or ((n mod 1) < > 0)) then

  • print( "Illegal n in function!" )

  • else

  • // Old module body follows...

  • if((n = 0) OR (n = 1)) then

  • Fibonacci returns 1

  • else

  • New_Fibonacci returns Fibonacci(n-1) +

  • Fibonacci(n-2)

  • endif

  • endif

  • endfunction // Fibonacci


But that solution had problems l.jpg
But That Solution Had Problems!

  • Inefficient because we’re doing the test unnecessarily at each iteration

  • Functions must always return a value

  • Mixes “correctness” part with “carrying out algorithm” part

  • Doing more than one thing

  • Functions cannot print!


Slide58 l.jpg

Design by Contract

  • Like a business contract (house-building)

  • The module’s client is the caller of the module.

  • The supplier is the called module

  • The pre-condition states the responsibilities of the client

  • The post-condition states the guarantees made by the supplier


Slide59 l.jpg

Module Documentation as a Contract

  • Make both client and supplier responsibilitiesexplicit as part of documentation.

  • Both client and supplier know what is expected of them and what to expect of the other.

  • function Fibonacci returnsa num(n isoftype in num)

  • // Purpose: Returns nth fibonacci number

  • // Pre-condition: n is a non-negative integer

  • // Post-condition: The returned number is the nth// number in the fibonacci

  • // sequence




Where ya been krogers what s in the bag l.jpg

Answer 1

beans

canned peaches

bread

chips

coke

dental floss

ice cream

shoe polish

John Tesh CD

carrots

Answer 2

groceries

LB

Where ya been?Krogers.What’s in the bag?


Data abstraction l.jpg
Data Abstraction

  • Separating the essence from the particular instance or implementation.

  • The most fundamental technique:

    • Descriptive identifiers that are brief and informative (not cryptic or cute)

  • Example:

  • For the purpose of representing an employee’s ID number, which one features the highest data abstraction?

  • this_num isofype Num

  • someone_num isoftype Num

  • employee_ID_num isoftype Num


Data abstraction64 l.jpg
Data Abstraction

Data Abstraction allows us to:

  • Combine data that belongs together

  • Consider the logical grouping of data

  • Apart from the specific implementation

    Records are the mechanism for data grouping.

  • Defined in the algorithm

  • A heterogeneous collection of data(we can mix different types of data in a single structure)


Representing related data l.jpg
Representing Related Data

  • Information concerning a student:

    name isoftype String

    age isoftype Num

    is_male isoftype Boolean

    letter_grade isoftype Char

  • This should be abstractly grouped together!


Grouping related data together l.jpg
Grouping Related Data Together

name (String)

age (Num)

is_male (Boolean)

Letter_grade (Char)


Record definition example l.jpg
Record Definition Example

Student_Type definesa record

name isoftype String

age isoftype Num

is_male isoftype Boolean

letter_grade isoftype Char

endrecord // Student_Type

Instead of a collection of 4 variables, we have defined a new data type and now have the ability to create variables of Student_Type, each with the appropriate information.


Record templates l.jpg

LB

Record Templates

Definition:

<Type Name> definesa record

<field definitions>

endrecord

Declaration:

<Identifier> isoftype <Type Name>


Record example l.jpg
Record Example

Student_Type definesa record

name isoftype String

age isoftype Num

is_male isoftype Boolean

letter_grade isoftype Char

endrecord // Student_Type

Stu1, Stu2, Stu3 isoftype Student_Type

This creates three variables of type Student_Type. Each of these variables contains information about name, age, is_male, and letter_grade.


Creating new data types l.jpg
Creating New Data Types

  • We use records to construct new “user-defined” data types

  • The newly created data type is treated like any of the “built-in” types

  • Cannot read or print user defined data types directly. Since the new type is new to the language, read and print don’t know how to process the request.

  • Creating variables of a new data type is a two-step process: define & then declare

  • Creating the new data type does not provide any variables, only the template by which variables may then be declared.


Creating new data types example l.jpg
Creating New Data Types Example

Task:

Create a database to keep track of the kids in an elementary school

To make the example simple, we will only store:

  • Student number

  • Age

  • Grade in math this year


Creating new data types example72 l.jpg

Creating New Data Types Example

Step 1: Define the new type:

Kid_Record definesa Record

student_num isoftype Num

age isoftype Num

grade isoftype Char

endrecord

Step 2: Declare Record variables of this new type:

mary, zach, herbert isoftype Kid_Record

best_grade isoftype Char


Accessing fields of records l.jpg
Accessing Fields of Records

  • We can access the individual fields of a record using the dot (.) operator:

    <var_name>.<field_name>

    Examples:

    • mary.student_num <- 45137

    • mary.age <- 13

    • mary.grade <- ‘A’

    • best_grade <- mary.grade

    • zach.grade <- best_grade

    • zach.age <- 12


Operators and records l.jpg
Operators and Records

Assignment works just as before with built-in types (both sides must be of the same type):

  • // assigns ALL fields in single op

    • zach <- mary

      Printing and reading can only take built-in types as parameters, so we print and read fields, not records.

      read(zach.student_num, zach.age, zach.grade)

      print(zach.student_num, zach.age, zach.grade)


Using new data types l.jpg
Using New Data Types

Note: Items of the form

  • some_record_var.some_field

  • are L-values - they may appear on the left of an assignment & may be passed as in, in/out, or out parameters.


  • Combining abstractions l.jpg
    Combining Abstractions

    • Often, data abstractions (for example, records) need corresponding procedural abstractions (modules) as helpers.

    • Common examples include:

      • Modifier modules: procedures usedto read in or update data values

      • Accessor modules: procedures used to print out information in a record, or functions which return data values to other modules

    • We will revisit this idea when we talk about behavioral abstractions later in the course


    Combining abstractions77 l.jpg
    Combining Abstractions

    • For example:

    • Student_Rec definesa Record

    • name isoftype String

    • ssn isoftype Num

    • num_hours isoftype Num

    • endrecord

    • procedure Print_Student(somebody isoftype in Student_Rec)

    • // An accessor module which prints out all // data values stored in a Student_Rec print(“Name: ”, somebody.name)

    • print( “SSN: ”, somebody.ssn )

    • print( “Hours:”, somebody.num_hours )

    • endprocedure


    Combining abstractions78 l.jpg
    Combining Abstractions

    • procedure Read_Student (somebody isoftype out Student_Rec)

    • // A modifer module which obtains data// values and stores them in a Student_Rec

    • print(“Enter the student’s name: ” )

    • read( somebody.name )

    • print(“Enter the student’s ssn: ” )

    • read( somebody.ssn )

    • print( “Enter the student’s hours taken: ” )

    • read( somebody.num_hours )

    • endprocedure // Read_Student


    Combining abstractions79 l.jpg
    Combining Abstractions

    • ...

    • Student_1 isoftype Student_Rec

    • // call to modifier

    • Read_Student(Student_1)

    • // call to accessor

    • Print_Student(Student_1)

    • ...

    • Student_2 isoftype Student_Rec

    • // call to modifier

    • Read_Student(Student_2)

    • // call to accessor

    • Print_Student(Student_2)


    Records within records l.jpg
    Records Within Records

    There is nothing to prevent us from placing records inside of records (a field within a record):

    Date_Type definesa record

    day, month, year isoftype num

    Endrecord

    Student_Type definesa record

    name isoftype string

    gpa isoftype num

    birth_day isoftype Date_Type

    graduation_day isoftype Date_Type

    endrecord


    Record within records l.jpg

    day month year

    name

    gpa

    day month year

    day month year

    Record Within Records

    Date_Type:

    Student_Type:

    bob isoftype Student_Type

    bob.birth_day.month <- 6

    birth_day

    graduation_day


    Types vs variables l.jpg
    Types vs. Variables

    • TYPE Definitions

      • Create templates for new kinds of variables

      • Do not create a variable – no storage space is allocated

      • Have unlimited scope

    • VARIABLE Declarations

      • Actually create storage space

      • Have limited scope - only module containing the variable can “see” it

      • Must be based on an existing data type


    Anonymous data types l.jpg
    Anonymous Data Types

    • This_Record isoftype record

    • silly isoftype Num

    • stupid isoftype Char

    • endrecord // This_Record

    • Anonymous data typescombine the declaration of a complex variable with a data type definition.

    • Thus, the data type itself has no name.

    • Some languages allow this

    • Removesbenefits of data typing

    • Is in general bad; do not do this even if a language allows it


    Anonymous data types84 l.jpg
    Anonymous Data Types

    • If two different variables are anonymous data types with identical structure, then they can hold the same data, but:

    • They are not of the same type; they are of no type

    • Cannot assign one to another

    • Cannot pass grouped data between them via parameter

    • Must assign field-by-field

    • Must make changes in multiple places

    • Don’t do it!!

    • In our pseudo-code, cannot do it