Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 69

UNIT 2

Models and Design


• Functional Model – Features, Recursive processes,
Scope rules, Tail recursion, Checking correctness of
Iterative process.
• Imperative Model – Basics, Specifications and
Prototyping, Stepwise Refinement, Proof Rules –
Basics, For loops, Goto and Exit loops, Functions
and Procedures,
• Problem Solving using Greedy strategy - Knapsack
problem, Huffman code generation algorithm.
Introduction
• The actual computation done when a computer
program is executed on a computer, can in
general, be represented by two kinds of
models:
– Declarative Model (functional model)
– Imperative Model (structured programming )
Functional Model/Declarative Model

• This model is oriented towards specification of


how various entities taking part in a
computation are related.
• These relationships are expressed as functions.
• The emphasis is on what is to be
achieved rather than how to achieve it.
Imperative Model
• The word ‘imperative’ denotes commands
being given to some execution agent (a
computer in our case).
• This model is generally given in terms of an
actual program in some computer
programming language or a pseudo-code.
• The emphasis is on how to do something,
rather than what is to be done.
Characteristics of A good model

• Primitive expressions which represent the


simplest objects with which the model is
concerned.
• Methods of combination which specify how the
primitive expressions can be combined with one
another to obtain compound expressions.
• Methods of abstraction which specify how the
compound objects can be named and
manipulated as units.
Functional Model/Declarative Model

• The functional model is very close to


mathematics; hence functional algorithms are
easy to analyze in terms of their correctness
and efficiency.
• A functional algorithm can serve as a
specification for the development of
algorithms in other models of computation.
Continue….. functional model
• In the functional model of computation every
problem is viewed as an evaluation of a
function.
• The solution to a given problem is specified by
a complete and unambiguous functional
description.
Features of Functional Model
1. Primitive expressions which represent the
simplest objects with which the model is
concerned.
2. Definition of one function in terms of
another (Substitution)
3. Definition of functions using conditionals.
4. Inductive definition of function
1. Primitive expressions
• The basic primitives of the functional model
are constants, variables, and functions.
• Elements of the sets  N, ℤ, R  are the constants.
Also, the elements of the set  B = {true, false}
are constants
• Variables are identifiers which refer to data
objects (constants). Identifiers like n, a, b, x and
so on, to refer to various data elements used in
functional algorithms For e.g. x = 5 and y = true
{….. -1 , 0, 1, 2,3…..}

{0, 1, 2,3…..}

{1/2, 2/3,3/4………..}

{∏, e, -2 ∏,…...}
Primitive function
• The primitive functions of the type
– f : ℤ × ℤ → ℤ
–  f : R × R → R

• Also, the following functions are assumed to be available.


• ∧ :   B× B  → B  (and),
• ∨ :   B×B   → B  (or), and
• ¬ :  B → B  (not).

 
2. Substitution of Functions   
• Definition of one function in terms of another
and the evaluation of such functions through
substitution.
– Example 1
– Finding the square of a natural number. We can
directly specify the function square, which is of the
type 
Example 1 Continue…
– square :  N → N
in terms of the standard multiplication function:
• * : N  × N  → N  as
square(n) = n * n

Here, we assume that we can substitute one function for


another, provided both of them return an item of the same
type. To evaluate, say, square(5), we have to thus evaluate 5 *
5.
Example 2

• Finding the sum of two squares. We can define


function sum_squares : N  × N  → N  as
follows:
– sum_squares(x, y) = square(x) + square(y)
Example 3

• Using local variables, suppose we wish to compute the


function
• f(x, y) = x(1 + xy)2 + y(1 – y) + (1 + xy)(1 – y)

We can also express this as:


• a = 1 + xy, b = 1– y, 
so f(x, y) = xa2 + yb + ab.
• Thus we can avoid multiple computations of 1+ xy and
1– y by using local variables a and b.
3. Definition of Functions using Conditionals

• Example 1
Finding the larger of two numbers. Let us
define a function
max :  N × N  →  N
We define this function as
• While defining the function max, we have
assumed that two natural numbers can be
compared using the ≥ function to determine
which is larger.
• The basic primitive used in this case is if-then-
else.
• Thus if a ≥ b, the function returns a as the
output, else it returns b.
• Note that for every pair of natural numbers as its
input, max returns a unique number as the output
and hence it stick to the definition of a function.
Example 2

• Finding the absolute value of x. We define the


function
Inductive Definition of Functions   
• All the examples we have seen so far, are of
functions which can be evaluated by
substitutions or evaluation of conditions.
• Let us now consider functions as inductively
defined computational processes.
• Inductive: characterized by the inference of
general laws from particular instances
.

Example 3

• Computing the GCD of two numbers. We can define


the function

For example, for the specific case of computing gcd(18,


12), we have
 
gcd(18, 12) = gcd(6, 12) = gcd(6, 6) = 6
Why it is function
• It is a function because, for every pair of
positive integers as input, it gives a positive
integer as the output.
• It is also a finite computational process,
because given any two positive integers as
input, the description unambiguously tells us
how to compute the solution and the process
terminates after a finite number of steps.
Example 1
• All mathematically valid specifications of functions are not
algorithms. For example,

• is mathematically a perfectly valid description of a


function of the type
(with the signature) sqrt : N  → N .
However, the mathematical description does not tell us how
to evaluate the function and hence it is not an algorithm
Example 2
• f :   N→N 
• f(n) = 0           for n = 0 and
• f(n) = f(n + 1) – 1       for all n ∊  N
There is a unique solution for this specification: f(n)= n ∀n ∊ N.
However, it is not a valid algorithm, because in order to
evaluate f(1), we have to evaluate f(n + 1) for n = 1,2,3 which
leads to an infinite computational process.
One can rewrite the specification of the above function, f(n), in
an inductive form, as
Now this indeed defines a valid algorithm for computing f(n).
Mathematically , the specifications for f(n) and g(n) are equivalent, in that they
both define the same function.
However, the specification for g(n) constitutes a valid algorithm whereas for f(n)
does not.
For successive values of n, g(n) can be computed as
Conclusion
• Thus, we see that a specification of a function is
an algorithm only if it actually defines a precise
computational procedure to evaluate it.
• All of the following constitute an algorithmic description:
1. It is directly specified in terms of a pre-defined function which
is either primitive or there exists an algorithm to compute the
function.
2. It is specified in terms of the evaluation of a condition.
3. It is inductively defined and the validity of its description can
be established through the principle of Mathematical Induction.
4. It is obtained through a finite number of combinations of the
steps (1), (2), and (3) using substitutions
Types of processes
• Complex functions can be algorithmically
defined in terms of two main types of
processes—
– Recursive 
– Iterative.
Recursive Processes
• Recursive computational processes are characterized
by a chain of deferred operations.
• As an example, we will consider an algorithm for
computing the factorial of an integer n (n!).
• The computational process, in special case of n = 5, looks as
follows:
• factorial(5) = (5 × factorial(4))
= (5 × (4 × factorial(3)))
= (5 × (4 × (3 × factorial(2))))
= (5 × (4 × (3 × (2 × factorial(1)))))
= (5 × (4 × (3 × (2 × (1 × factorial(0))))))
= (5 × (4 × (3 × (2 × (1 × 1)))))
= (5 × (4 × (3 × (2 × 1))))
= (5 × (4 × (3 × 2)))
= (5 × (4 × 6))
= (5 × 24)
= 120
 
Growing and  shrinking process
• A computation such as this is characterized by a
growing and shrinking process.
• In the growing phase each “call” to the function is
replaced by its “body” which in turn contains a “call”
to the function with different arguments.
• In order to compute according to inductive definition,
the actual multiplications will have to be postponed
till the base case of factorial(0) can be evaluated.
• This results in shrinking.
Growing and  shrinking process
• Once the base value is available, the actual
multiplication can be carried out resulting in a
shrinking process.
• Computational processes which are
characterized by such “deferred” computations
are called recursive.
Analysis of Correctness and Efficiency

• Correctness   The correctness of the factorial(n) functional


algorithm can be established using the Principle of Mathematical
Induction (PMI).
• The algorithm adheres to an inductive definition, and consequently
be proved correct by using PMI.
• Even though the proof of correctness may seem obvious for this
example, we give the proof to emphasize and clarify the distinction
between a mathematical specification and an algorithm that
implements it.

• Correctness   Show that ∀ n ∊  , factorial(n) = n!, that is, the


function factorial implements the factorial function.
Correctness of factorial function
• Proof   By PMI on n.
• Basis   When n = 0, factorial(n) = 1 = 0! by definitions
of factorial and 0!.
• Induction Hypothesis   For k = n – 1, k ≥ 0, we
have factorial(k) = k!.
• Induction Step   Consider factorial(n).
factorial(n) = n × factorial(n – 1)
= n × (n – 1)!         by the induction hypothesis
= n!                 by the definition of n!

Hence the function factorial implements the factorial function n!.


Efficiency 
• The time required to execute the factorial
algorithm is directly proportional to the number
of multiplications that have to be carried out
and the number of function calls required. We
can derive it in the following manner.
• Let T(n) be the number of multiplications
required for a problem of size n (when the input
is n). Then, from the definition of the function
factorial we get,
Efficiency 

Let T(n) be the number of multiplications required


for a problem of size n (when the input is n). Then,
from the definition of the function factorial we get,
• T(0) is obviously 0, because no multiplication is
required to compute factorial(0) = 1 as the
result.
• For n > 0, the number of multiplications
required is one more than that required for a
problem of size n – 1.
• This is a direct consequence of the recursive
specification of the solution. We can solve the
equation by telescoping, that is,
Scope Rules
• Word scope is related to free and bound
variables.
• These concepts play an important role in
programming.
• They also exist in mathematics as we illustrate
in the following examples.
Example
• Consider the expression

• It contains the following names a, b, n, f.

• Of these we don’t know what a, b, and f denote, except that we can assume


that a and b are natural numbers and f is a function on natural numbers.

• Hence the names a, b, and f are called free in the expression  . However n is


said to be bound in the sense that the expression makes it clear
that n ranges over the interval [a, b]

•  n is local to the summation function.


• Consider the following indefinite integral

• It contains z, f and g as free names. The other


names x, u and y are bound. The respective
scope of the bound variables is shown as
Tail-recursion and Iterative Processes

• Tail-recursion reduces the problem of space complexity which

occurs in recursive process due to deferred computations.

• For example, the algorithm for computing  factorial (n)

discussed in  has a space complexity of O(n) as a consequence of

deferred computations.

• These kind of inefficiencies can be removed by describing

alternative algorithms for these problems using tail-

recursion which lead to iterative computational processes.


Iterative algorithms
• The crucial idea in iterative algorithms is to
represent the state of computation at each
stage in terms of auxiliary variables
• So as to obtain the final result from the final
state of these variables.
• We may think of the state of a computation as
a collection of instantaneous values of certain
entities.
Iterative algorithms
• Example: Iterative computation of factorial:
• Consider three auxiliary variables f, c, and m.
• This is the same as factorial(n) if the initial
values are m = n, c0 = 0, and f0 = 1 respectively.
• The resulting algorithm is described here.
– factorial(n) = fact_iter(n, 1, 0),
• where the auxiliary function fact_iter :  N x P x N P
factorial(5) = fact_iter(5, 1, 0)
= fact_iter(5, 1, 1)
= fact_iter(5, 2, 2)
= fact_iter(5, 6, 3)
= fact_iter(5, 24, 4)
= fact_iter(5, 120, 5)
= 120
• In recursive process for computing factorial(n) is characterized
by a growing and shrinking process due to deferred
computations.
• In contrast, there is no growing process in the iterative version.
• The results of the successive stages are captured in the value
of f.
• The time complexity of the iterative algorithm is clearly O(n)
which is the same as that of the recursive one, whereas the
space complexity in this case reduces to O(1).
• This is because, at any stage, the instantaneous values of only
three variables are required to be stored.
Correctness of an Iterative Process
• The correctness of an iterative process can be
established by an analysis of the invariant
condition
• To Show    For all m, f, c such that 0 ≤ c ≤ m
• Proof   Using PMI (weak version) on (m – c).
• Basis   (m – c) = 0 or (m = c).

• Induction Hypothesis   For some k = (m – c) ≥ 0,

• Induction Step   Let (m – c) = k + 1 > 0. Then


• Then we can prove the correctness of the
function factorial(n) as follows:

• On the other hand, the invariant condition


encodes the above proof of correctness
through a description of state changes.
• At the initial stage, when c = c0, the invariant
condition gives us    
• At the final stage, when c = m, the invariant
condition gives us    which is the
final value that the function returns.
• According to the initial invocation
of fact_iter from the function factorial, the
initial values are f0 = 1, c0 = 0, and m = n. Thus
the final value of f is 
Imperative Model
The imperative model of computation
• The functional model is attractive from the point of view
of ease of algorithm and correctness analysis, imperative
models of computation are more commonly used in
practice mainly because of reasons of efficiency.
• In particular , Imperative programming language like
Fortran and C have been thoroughly optimized through
years of research, and programs compiled in these
languages in general work faster
• Here we will introduce the basics of an imperative
computation.
The imperative model of computation
• In the case of both the factorial and Fibonacci computations,
iterative process is more efficient than recursive process.
• However, we had used a functional model to describe iterative
processes in which we introduced the notion of the state of
the computation.
• A careful look at the computation mechanism of iterative
processes reveals that we have a starting state from which the
desired final state is obtained.
• For describing iterative processes, it is convenient to use a
model of computation which merely describes state changes.
The imperative model of computation

• Imperative model of computation allows us


to reflect the effect of change of state in the
model.
• The state of a computation is a collection of
instantaneous values of certain quantities.
• A state change occurs if at least one of the
quantities comprising the state is changed.
The imperative model of computation
• The imperative model of computation uses
instructions or commands to make the desired
state changes.
• Hence the concept of a variable in the imperative
model is that, it is a quantity whose value can be
changed through an appropriate command.
• The primary command which does this in the
imperative model is the ‘assignment’ instruction
The imperative model of computation

• The Imperative model uses following


constructs:
– Variables and the assignment instruction
– Assertions
– The if-then-else instruction
– The while-do instruction
– Functions and procedures in the imperative model
Variables and the assignment
instruction
• In imperative model we will use variables to store the state of a
compuatation.
• A “declaration” of variables to be of a certain type with statement
like
• Int a, b // creates and reserves two locations with the names a and b
in which integer values can be stored
• a=2; //state of the variables is a=2 b=(empty)
• b=a; //change the state to a=2 b=2
• On the left of the = operator must be a single varible whose state is
being updated, and on the right must be an expression comprising
operators, variables and values of same type as the variable
specified in the left
Variables and the assignment instruction

• As a result of this, in the imperative style, state


changes can be performed only one at a time.
• As an example of an imperative style
algorithm using the assignment instruction, let
us consider the following problem of
swapping the contents of two varibales.
Variables and the assignment instruction
• Assume that the initial contents of a and b are a0 and b0
respectively, we can describe the initial and the final state as:
– Precondition: (a=a0)^(b=b0)
– Post condition: (a=b0)^(b=a0)
• We can achieve this using following algorithm
– /*assert A:(a=a0)^(b=b0)
–{
– temp=a;
– a=b;
– b=temp;
–}
– /*assert B:(a=b0)^(b=a0)
Assertion
• In the algorithm stated above there are statements
labeled “assert” about the state of the computation.
• These are not instructions to be executed but are
essential documentation necessary for correct
design of imperative algorithms.
• such statements are called assertion.
• The precondition and post condition are assertions
about the initial and final states of the algorithm
respectively.
IF-THEN-ELSE instruction
• The IF-THEN-ELSE instructions which provide
the basic mechanisms for the flow of control in
an imperative algorithm.
• IF-THEN-ELSE instruction is the basic tool for
decision making in imperative style
programming.
• It is a directive for executing onr out of two
possible sequences of instruction depending on
logical condition.
IF-THEN-ELSE instruction
• The structure of the IF-THEN-ELSE is
if (C)
S1
else
S2
• Here S1 and S2 may either be simple
instructions or they may even be compound
instructions enclosed in a pair of { …. }
Brackets.
IF-THEN-ELSE instruction
• Given that the pre condition of IF-THEN-ELSE
instruction is an assertion A, we may rewrite it as
follows by inserting appropriate assertions
/* assert A:…..*/
if (C) /*assert A ^ C*/
S1
else /*assert A ^ - C*/
S2
IF-THEN-ELSE instruction
• Example: swap the values of variable a and b if a>b
/* assert A: (a=a0)^(b=b0)*/
if (a>b)
/* assert A ^(a>b)*/
{
Temp=a;
A=b;
B=temp;
}
/* assert B: ((a<=b0)^(a=a0)^(b=b0)) V ((a=b0) ^(b=b0))*/
The while do instruction
• The primary iterative construct in this model which
does this is the while do.
• While (C)
• S1 // repeate S1 while the boolean condition C is
true.
• After each execution of the instruction S1 the
condition C is evaluated again to determine whether
it is true or not. The process is repeated if C is true;
otherwise the while do instruction is terminated.
Function and procedures in the imperative
model
• Procedures and functions enable the
programmer to concentrate on achieving the
goal—divide and conquer.
• A function is used when we wish to return a
single value from the sub-program to the
calling routine.
• The transfer of control and return of value are
accomplished through a stack.
Function and procedures in the imperative
model
• A procedure though similar to a function,
does not return a value explicitly.
• The method of invocation of a procedure is
also different.
• The return of value—or the result of
computation with reference to a procedure is
through its parameters.
Function and procedures in the imperative
model
• Both procedures and functions fall under the general
category of sub-programs or sub-algorithms.
• A subprogram is an independent component of a
program and for this reason it is defined separately from
the main routine or program.
• The purpose of this sub-program is to perform some
computation only when required and it is executed under
the control of the main program (algorithm).
• This computation may be performed with zero or
more parameters passed by the calling routine.
Function and procedures in the imperative
model
• The format used is the same as that for
algorithms except that a return statement
replaces an exit statement and the list of formal
parameters follow the sub-program’s name.
• A sub-program may invoke another sub-program
and if properly implemented, it may even invoke
itself recursively.
• One of the better known recursive algorithms is
the factorial generation algorithm.
Function and procedures in the imperative
model
– If (N = 0) then return (1)
– else return (N*factorial(N – 1))
• A function is used when one wishes to return a
single value to the calling program or sub-
program.
• The transfer of control is via invocation in the
calling procedure and return of value is
implemented through sub-program parameters
or through the return statement.

You might also like