Lecture Notes

for

CSCI 1301: Great Ideas in Computer Science

(c) 1993 - 2007 John E. Howland, All Rights Reserved

Department of Computer Science

Trinity University

One Trinity Place

San Antonio, Texas 78212-7200

Internet: jhowland@ariel.cs.trinity.edu

1 Introduction

1.1 What is Computer Science

These notes focus on giving a variety of answers to the question "What is Computer Science?"

When we ask this question, consider that we don't have car science or telephone science, dishwasher science, etc. Since computing is now an integral part of almost every aspect of modern society, perhaps we should ask whether or not computer science is subsumed by such classical disciplines as mathematics, physics, neuro-science, electrical engineering, linguistics, logic and philosophy. In fact, some computer scientists consider this to be the case and consider it their goal to so thoroughly integrate the various parts of computer science back into its parent disciplines so that it no longer has a separate identity as computer science. This somewhat controversial view is not widely held.

1.1.1 Misconceptions

Before we elaborate on what computer science is, let's consider some possible definitions of the field of computer science and discuss the deficiencies of each.

1.1.1.1 Computer Science is the Study of Computers

Much of the important scientific work which lays the foundation of computer science was done between 1915 and the mid 1940's. This was, of course, before any electronic computers had been built. The scientists doing this work were, for the most part, mathematicians. They were interested in the structure and organization of systems for computation. They wanted to determine just what computations could be performed by their systems and gave designs for simple theoretical machines which were sufficient to compute most of the functions they desired. Much of the theoretical basis for computer science was developed before computers existed, so a more inclusive definition is perhaps needed.

1.1.1.2 Computer Science is the Study of the Programming of Computers

This is a popular view held my many, perhaps because the programming of computers is one of the more visible activities of many of those involved in computer science. However, this definition is not nearly inclusive enough since many activities which a computer scientist might engage in involve no programming at all. For example, it may be necessary to give a mathematical proof of correctness of an algorithm, or a systems analyst may need to study a system in detail before beginning a design of a data processing system. A computer engineer may need to design a simulation model for a cache memory system which will buffer the speed difference between a fast processor and its memory system. Programming is of fundamental importance to computer science since it is the requisite laboratory skill which most computer scientists posses inorder to be able to pursue their work, but that work often involves much more than just programming.

In the previous paragraph a number of terms were used with which you may not be familiar. Do not worry about this now as definitions for most of these will be given later.

1.1.1.3 Computer Science is the Study of the Uses and Applications of Computers and Software

Since the personal computer revolution which began in the early 1980's and continues today, the pervasive application of computers to nearly all fields has popularized the view that computer science is concerned primarily with computer applications and applications software. It is thought by some that computers, without their widespread general applicability to a variety of fields, would not constitute a sufficient body of knowledge to warrant being considered a body of scientific information. They also argue that it is sufficient to be trained in a few computer applications software packages in order to work as a computer specialist. Clearly, the field of computer science is much larger than just computer applicaitons software.

1.1.1.4 Computer Science is the Study of Computing Machines and Phenomenon Surrounding their Use

This definition is, perhaps, a little better than those given earlier because it is a little more encompasing. However, it is deficient in that it focuses primarily on the computer itself rather on some other, perhaps more fundamental, ideas.

1.1.1.5 Computer Science is the Study of Problem Solving via Mechanisms

In this definition we have the idea that computer science is concerned with problem solving and it is certainly true that problem solving is a principle focus of computer science. This definition restricts the field to problem solving using machines and it is here that the definition is too general because it admits the use of machines which are not computers or which are not functionally equivalent to computers.

1.1.2 Computer Science as the Study of Algorithms

An algorithm is an abstract recipe, prescribing a process that might be carried out by a human, by a computer or by some other means. We take the view, in this book, that computer science is the study of algorithms.

Using this definition one might consider some of the sub areas of computer science to involve the design, structure, analysis, efficiency and correctness of algorithms, the mathematical properties of algorthms, the data they manipulate, the languages in which they are implemented and the machines on which they are interpreted.

Finally, one might study the limitations of algorithms.

1.2 Notation

Most bodies of scientific information have one or more generally accepted notations for expressing the ideas of that science. Chemistry has a notation for the molecular organization of chemical compounds, such as CO2. Mathematical notation is widely used in all of the sciences. Notation is developed to fill a void for communication of complex technical ideas when ever ordinary natural language is either too verbose or lacking in vocabulary.

1.2.1 Notation as a Tool for Thought

When the human mind is engaged in thought of an explicit nature, the speech center of the brain is involved. This means that we are verbalizing our thoughts even though we may not actually be speaking. When we are thinking we are necessarily using language or a notation of some sort to accomplish this verbalization. Hence it follows that notation, particularly the scientific notation of the field of science is a critical tool for creative thinking.

1.2.2 Abstraction

Abstraction is a powerful tool of notation which is particularly useful in handling complexity. Abstraction is the naming of an idea so that it may be easily referred to in more complex settings. For example, in mathematics the idea of computing the average of a sequence of n numbers x1, x2, ..., xn is sometimes written as ave(xi). Similarly, the derivative of a function f(x) is written as f'(x).

1.2.3 Modeling

In computer science, as is the case in many scientific disciplines, modeling plays a fundamental role. Computer scientists build models so that they can study, analyze and predict the behavior of systems which they are studying. As students of computer science you will build models so that you can conduct experiments on a variety of different topics. Where ever possible, these models will be designed using some notation which is useful, not only for thinking and analysis, but also as a means of implementing that model on a computer.

1.2.4 Scheme

Scheme is a notation which is useful for exposition of computing ideas in a functional manner. It derives many of its features from ordinary mathematical notation. In addition, Scheme notation is directly executable on nearly every brand of computer system and is available free of charge so that it is ideal for many kinds of programming activity. It is particularly well suited for laboratory experimentation due to its interactive nature. Occasionaly we may use some Scheme notation in our model building.

1.2.5 J

J is a new functional notation which shares many of the features of Scheme and is also very well suited for expositiory and experimental use as a notation for computer science. We will make use of the J notation as a purely expository notation. In addition, we will find that most of such expositions provide working models on which we can experiment. We will use J in the description of virtually every area of computer science discussed in this text. You will need to make a little effort to develop some elementary programming skills so that you can carry out simple laboratory experiments as well as be able to read and understand expositions written in J. However, it should be emphasized that the primary focus of our programming skills will be to learn to read and understand existing programs rather than learing to create our own independent solution to programming problems.

1.3 An Introduction to the J Notation

Since we observed in 1.2.1 that verbalization of notation is important, we use ideas and terminology from natural language (English) to describe the important features of J. This includes both syntax (the rules of grammar) and semantics (what J sentences mean).

1.3.1 J Sentences

In J, a sentence is a collection of items (words). Word formation rules (which we will later learn) are used to break a sentence into words. For example:

 2 + 3
is an example of a simple J sentence. It is verbalized as "2 plus 3". Compound sentences are formed by using parentheses to form subordinate clauses (sub sentences). We don't pronouonce the parentheses unless we have a compound sentence which contains another sentence imbedded within as a subordinate clause. Most J sentences are imperative, that is, they convey some action to be performed by the reader. In the above example, the reader is directed to add 2 and 3 producing a result of 5.

A J computer system is in a repetitive process of reading the user's sentence, evaluating that sentence (performing the imperative action of the sentence) and printing the result of the sentence. We say that the J system has a REPL (Read, Evaluate and Print Loop).

The general form of a J sentence (version 1) is:

1.3.2 Sentence Form


<noun>
or

<verb> <sentence>
or

<sentence2> <verb> <sentence1>
Verbs have one or two objects. Examples are:

2 - 3
- 5
The first sentence is read "2 subtract 5", producing a result of negative 1. The second sentence is read as "negate 5", producing a result of negative 5. Verbs which are applied to just one item (negate for example) are called monads. Verbs which are applied to two items (addition for example) are called dyads. The terminology <verb> or <sentence> is a notation (actually a meta notation) to describe that a part of speech called a verb or sentence appears in a particular position in the syntax (rules of grammar) of a sentence. Notice that in defining a sentence we are saying that a sentence is defined in terms of itself. We say that such a definition is recursive, i.e. the definition refers in part to itself. This is not a circular definition since a sentence is also defined as a noun. Sentences may have sub-sentences. In this case we say we have a compound sentence. For example:
(2 * 5) - 3
% - 2
The first sentence is read "the quantity 2 times 5, subtract 3", producing a result of 7. The second sentence is read "reciprocal of negate 2", producing a result of negative 0.5 . We call such sentences compound sentences. Notice also that there is an implied order in this imperitave sentence. The subordinate sentence (2 * 5) must be read or performed before the subtraction can be performed. There is a "natural" order of evaluation which is derived from a left to right reading of a sentence. For example,

2 * 3 + 4
evaluates to the value 14. This surprizing result is derived from the left to right reading as "2 times the quantity 3 + 4". You are perhaps expecting a value of 10 for this expression having learned that multiplications are always performed before addition. This rule was arbitrarily choosen and has no mathematical basis. To achieve the other order of evaluation in J, one must write:

(2 * 3) + 4
which evaluates to 10. This sentence is read as "the quantity 2 times 3, plus 4.

In 1.3.2, <verb> and <noun> are meta notation variables which stand for the kind of object which would appear at that place in a sentence.

1.3.3 Evaluation Rule

If the sentence consists of just an noun, return the value of that noun. If the sentence is of the form:

<verb> <sentence>
first evaluate <sentence> ,using the same evaluation rule, then apply <verb> to the resulting value. Notice that this rule is defined in terms of itself. Such rules are said to be recursive. If the sentence is of the form:

<sentence2> <verb> <sentence1>
first evaluate <sentence1> , then evaluate <sentence2> and apply <verb> to these resulting values.

The values of a sentences consisting only of verbs and nouns are nouns. A noun in J is a constant value whose meaning is universally understood and never changes. Examples of nouns are 2 (the number), '21' (a list of two characters, namely 2 followed by 1. There are other types of nouns as we shall see later.

A pronoun in J is a symbol or name which has been bound to a noun. A pronoun may be used in place of a noun in sentences. For example,


t1 =: 5.52
defines a pronoun t1. Once so defined, t1 may be used as a noun as in the sentence

3 + t1
The value of a pronoun may change from time to time, depending on the binding, just as the pronoun she, in the English language, takes on different meanings depending on the context of reference.

A symbol may be bound to a verb creating what is called a proverb. For example we define


plus =: +
Then we write 3 plus 4. A proverb may be used in place of a verb in sentences. This is probably an unfamiliar concept in natural language since English does not have a mechanism to define new verbs. The J notation allows us to define pronouns and proverbs with equal ease. We could even write

minus =: +
but this would likely lead to confusion. We need to exercise common sense in the choice of symbols used to define pronouns and proverbs to improve the readability of our J sentences.

Pronouns and proverbs are the key to abstraction in J. They allow the binding of a complex value or verb to a name which can then be used to form more complex objects.

1.3.4 Making New Verbs

The real power of a notation which is useful for describing computational ideas is that the users of the notation may make their own verbs. This is something which most of us do not have an opportunity of doing in natural language.

1.3.5 Defining Verbs Explicitly

Suppose that the following definitions have been made. These definitions are not required to define J verbs explicitly, however, their use does make definitions somewhat easier to read.

noun =: 0
adverb =: 1
conj =: 2
monad =: 3
verb =: 3
dyad =: 4
locale =: 6
define =: : 0
The sentence

plus =: dyad define
x. + y.
)
constructs a verb (dyad). The words x. and y. are pronouns which are bound to the left and right nouns when the verb plus is used in a sentence. The last line of this definition, containing only ")", signifies the end of the definition script. The action of this verb is to produce a noun result of adding x. and y. .

10 plus 15
This sentence would produce a noun of 25. Actually, we could have defined this verb without using a script or binding a name to the definition. For example:

10 (dyad def 'x. + y.') 15
produces the result 25.

The sentence:


square =: monad define
y. * y.
)
defines a monad which squares. Then the sentence

square 5
produces the noun 25. This function could be defined without using a script or binding the name square as:

(monad def 'y. * y.') 5
which produces a result of 25.

square may be written using the J primitive *: . The expression


*: 5
produces a result of 25. We introduce a notation ==> which is read "produces a result of". The ==> is not J notation. It is used in these notes to indicate what value is obtained as a result of evaluation of the J sentence immediately to the left.

1.3.6 Conditional Definitions

Any notation for describing computation needs a method for creating action sentences which do one action if a certain condition is true and another action if that condition is not true. There is a special keyword if. to accomplish this. This word may only be used in explicit definitions. Here is an example:

maximum =: dyad define
if. x. > y.
  do. x.
  else. y.
end.
)

3 maximum 4 ==> 4
5 maximum 4 ==> 5.
We can use an alternate way of expressing this function as a monad. In this definition, both values are combined as a two item list.

maximum =: monad define
('x' ; 'y') =. y.
if. x > y
  do. x
  else. y
end.
)
This definition expects its two inputs to be combined using the link verb (";"), explained in section 1.3.9 below.

maximum 3 ; _4 ==> 3
maximum 3 ; 4 ==> 4
In this definition of maximum, the line ('x' ; 'y') =. y. separates the two input items in y. and binds the local name x to the first and y to the second.

1.3.7 Describing Data

So far, data items have been simple nouns such as 2, 3.5 or lists such as 'Hi there'. J allows the definition of lists of numbers by simply separating the numbers by one or more spaces. For example,

l1 =: 1 2 10 _9 3
creates a list of 5 numbers, 1, 2, 10, negative 9 and 3. The number of elements in a list is given by the tally (spelled #) verb.

#l1 ==> 5

l2 =: 'Hi there'
#l2 ==> 8
creates a list 8 characters.

1.3.8 Accessing the Parts of Lists

Consider the following definitions:

first =: {.
rest =: }.
Then

first l1 ==> 1
rest l1 ==> 2 10 _9 3
first l2 ==> H
rest l2 ==> i there
Next, consider the definition

from =: {
Then,

0 from l2 ==> H
3 0 2 from l1 ==> _9 1 10

1.3.9 Constructing Lists

As we saw in 1.3.7, we can type in lists as numbers separated by 1 or more spaces or we can type in lists of characters by enclosing them between quote (') characters. We can also build lists by using the append (,) verb.

1 , 2 ==> 1 2
'H','i' ==> Hi
'Hi',' ','there' ==> Hi there
'Hi','there' ==> Hithere
Another verb (i.) called integer builds lists of integers, starting with 0.

i. 2 ==> 0 1
i. 10 ==> 0 1 2 3 4 5 6 7 8 9
# i. 10 ==> 10
There are two verbs

box =: <
open =: >
which are useful when building lists.

box i. 5 ==>
+---------+
|0 1 2 3 4|
+---------+
Hence,

(box i. 5) , box i.2 ==>
+---------+---+
|0 1 2 3 4|0 1|
+---------+---+
which is a two element list. Consider

l3 =: (box i. 5) , box i.2
Then,

1 from l3 ==>
+---+
|0 1|
+---+
 open 1 from l3 ==>
0 1
tally open 1 from l3 ==>
2
1 from open 1 from l3 ==>
1
It is considered a domain error (out of the domain of definition) to apply the append verb to different types of data. For example,

1 2 3 , 'hi there' ==> domain error
The verb link (;) is designed to solve this problem by boxing its left input and right input, if necessary, producing a list of boxed items.

1 2 3 ; 'hi there' ==>
+-----+--------+
|1 2 3|hi there|
+-----+--------+
1 2 3 ; box 'hi there' ==>
+-----+--------+
|1 2 3|hi there|
+-----+--------+
In this latter example, the right input box 'hi there', was not boxed a second time since it is already boxed.

1.3.10 List Accessor and Constructor Equations

Given a non empty list x,

(first x) link rest x ==> x
and given two J items a and b:
first a link b ==> a
rest a link b ==> b

1.3.11 Summing the Elements of a Numeric List

As a programming example, we wish to solve the problem of summing the elements of a simple numeric list. To be a bit more precise, we assume that the object given to the verb list_sum which we will define is list and that all elements of the list are numbers. These assumptions will make the solution of this problem a bit simpler.

We begin the solution by observing that if the list, ls, is non-empty, then the solution can be expressed as (first ls) + list_sum rest ls. We call this type of solution the divide and conquer approach. That is, we have reduced the solution of the original problem to solution of two problems (an addition and summing a smaller list of numbers) each of which is smaller than the original problem. Moreover, one of the sub-problems is identical (except for summing a smaller list) to the original problem. This means we can use the same solution to that sub-problem as we did on the original problem. The only thing that is left is to decide what to return as an answer when list_sum eventually attempts to compute the sum of an empty list. How about zero?

Consider the following definition for list_sum.


list_sum =: monad define
if. 0 = tally y.
  do. 0
  else. (first y.) + list_sum rest y.
end.
)

list-sum 1 2 3 4 ==> 10
We can define a traced version of list_sum which will show some of the inner working of the list_sum function as follows:

display =: 1 !: 2 & 2
display is a helping monad which displays its input on the display console and then returns that input. Three other functions are used to trace functions. They are given below, but we will not discuss them until later.

trace =:  monad define
display y.
:
display (format x.),format y.
y.
)

entering =: 'Entering, input = '&trace
leaving =: 'Leaving, result = '&trace

traced_list_sum =: monad define
entering y.
if. 0 = tally y.
  do. leaving 0
  else. leaving (first y.) + traced_list_sum rest y.
end.
)

   traced_list_sum 1 2 3 4
Entering, input = 1 2 3 4
Entering, input = 2 3 4
Entering, input = 3 4
Entering, input = 4
Entering, input =
Leaving, result = 0
Leaving, result = 4
Leaving, result = 7
Leaving, result = 9
Leaving, result = 10
10
The J notation provides an abstraction for the above program as:

+/ 1 2 3 4 ==> 10
The phrase +/ is a verb which sums the items of a list.

1.3.12 Computing the Product of the First n Integers

There is a function from mathematics, called factorial, which computes the product of the first n (n >= 0) integers. Using ordinary mathematical notation we can define this function as:

factorial 0 = 1

factorial n = n * factorial (n - 1) , for n >0.

This leads us to the J definition:


factorial =: monad define
if. 0 = y.
  do. 1
  else. y. * factorial y. - 1
end.
)

factorial 0 ==> 1
factorial 4 ==> 24
factorial 6 ==> 720
As before, we can define a traced version of factorial which will show some of the inner working of the factorial function as follows:

traced_factorial =: monad define
entering y.
if. 0 = y.
  do. leaving 1
  else. leaving y. * traced_factorial y. - 1
end.
)
   traced_factorial 6
Entering, input = 6
Entering, input = 5
Entering, input = 4
Entering, input = 3
Entering, input = 2
Entering, input = 1
Entering, input = 0
Leaving, result = 1
Leaving, result = 1
Leaving, result = 2
Leaving, result = 6
Leaving, result = 24
Leaving, result = 120
Leaving, result = 720
720
The J notation provides a primitive definition for factorial (!).

!6 ==> 720
The abstraction for the list_sum program could be varied slightly to achieve another solution of the factorial verb as:

*/1 2 3 4 5 6 ==> 720
The phrase */ is a verb which computes the product of the items of a list.

Notice the similarity between the list_sum and factorial verbs.

1.3.13 Exercise

Define a list_product verb. What is the relationship between list_product and factorial?

1.3.14 Comparing Objects

J data objects are considered to be equal if they have the same structure and corresponding elemental values. For singleton objects, the comparison verb is =. For example,

1 = 5 ==> 0 
1 = 1 ==> 1
'a' = 'A' ==> 0
'a' = 0 ==> 0
'Hi there' = 1 2 ==> length error
'Hi there' = 'e' ==> 0 0 0 0 0 1 0 1
The match verb (-:) is available to compare structured items.

'Hi there' -: 1 2 ==> 0

1.4 J Vocabulary

The following table gives the primitive spelling of all J words. Verbs are denoted by normal typeface, giving the monad first, followed by the dyad. Cunjunctions are denoted by bold typeface and adverbs are shown in bold italic typeface. Nouns are shown in italic typeface.

Vocabulary >>  <<  Ndx  Usr  Pri  Phr  Dic  Rel  Voc  !:  wd  Help  Dictionary



Vocabulary ( Constants Controls Foreigns  ) 

= Self-Classify • Equal =. Is (Local) =: Is (Global)
< Box • Less Than <. Floor • Lesser Of (Min) <: Decrement • Less Or Equal
> Open • Larger Than >. Ceiling • Larger of (Max) >: Increment • Larger Or Equal
_ Negative Sign / Infinity _. Indeterminate _: Infinity
 
+ Conjugate • Plus +. Real / Imaginary • GCD (Or) +: Double • Not-Or
* Signum • Times *. Length/Angle • LCM (And) *: Square • Not-And
- Negate • Minus -. Not • Less -: Halve • Match
% Reciprocal • Divide %. Matrix Inverse • Matrix Divide %: Square Root • Root
 
^ Exponential • Power ^. Natural Log • Logarithm ^: Power
$ Shape Of • Shape $. Sparse $: Self-Reference
~ ReflexPassive / EVOKE ~. Nub • ~: Nub Sieve • Not-Equal
| Magnitude • Residue |. Reverse • Rotate (Shift) |: Transpose
 
. DeterminantDot Product .. Even .: Odd
: Explicit / Monad-Dyad :. Obverse :: Adverse
, Ravel • Append ,. Ravel Items • Stitch ,: Itemize • Laminate
; Raze • Link ;. Cut ;: Word Formation •
 
# Tally • Copy #. Base 2 • Base #: Antibase 2 • Antibase
! Factorial • Out Of !. Fit (Customize) !: Foreign
/ InsertTable /. ObliqueKey /: Grade Up • Sort
\ PrefixInfix \. SuffixOutfix \: Grade Down • Sort
 
[ Same • Left [. Lev [: Cap
] Same • Right ]. Dex ]: Identity
{ Catalogue • From {. Head • Take {: Tail •   {:: Map • Fetch
} Item Amend • Amend }. Behead • Drop }: Curtail •
 
" Rank ". Do • Numbers ": Default Format • Format
` Tie (Gerund)   `: Evoke Gerund
@ Atop @. Agenda @: At
& Bond / Compose &. Under (Dual) &: Appose
? Roll • Deal ?. Roll • Deal (fixed seed)
 
a. Alphabet a: Ace (Boxed Empty) A. Anagram Index • Anagram
b. Boolean / Basic c. Characteristic Values C. Cycle-Direct • Permute
d. Derivative D. Derivative D: Secant Slope
e. Raze In • Member (In) E. • Member of Interval f. Fix
 
H. Hypergeometric i. Integers • Index Of i: Integers • Index Of Last
j. Imaginary • Complex L. Level Of L: Level At
m. n. Explicit Noun Args NB. Comment o. Pi Times • Circle Function
p. Polynomial p: Primes • q: Prime Factors • Prime Exponents
 
r. Angle • Polar s: Symbol S: Spread
t. Taylor Coefficient t: Weighted Taylor T. Taylor Approximation
u. v. Explicit Verb Args u: Unicode x. y. Explicit Arguments
x: Extended Precision _9: to 9: Constant Functions




>>  <<  Ndx  Usr  Pri  Phr  Dic  Rel  Voc  !:  wd  Help  Dictionary

1.5 A J Programming Example

Suppose we wish to write a J verb which will select the elements of a simple numeric list which are greater than or equal to 0.

select_positive =: monad define
if. 0 = tally y.
  do. ''
  else.  if. 0 <: first y.
           do. (first y.) append select_positive rest y.
           else. select_positive rest y.
         end.
end.
)

   select_positive 1 2 3
1 2 3
   select_positive 1 _9 2 _3 3
1 2 3
As before we can make a traced version of select_positive which will help us follow the execution of this verb.

traced_select_positive =: monad define
entering y.
if. 0 = tally y.
  do. leaving ''
  else.  if. 0 <: first y.
           do. leaving (first y.) append traced_select_positive rest y.
           else. leaving traced_select_positive rest y.
         end.
end.
)
   traced_select_positive 1 2 3
Entering, input = 1 2 3
Entering, input = 2 3
Entering, input = 3
Entering, input =
Leaving, result =
Leaving, result = 3
Leaving, result = 2 3
Leaving, result = 1 2 3
1 2 3
   traced_select_positive 1 _9 2 _3 3
Entering, input = 1 _9 2 _3 3
Entering, input = _9 2 _3 3
Entering, input = 2 _3 3
Entering, input = _3 3
Entering, input = 3
Entering, input =
Leaving, result =
Leaving, result = 3
Leaving, result = 3
Leaving, result = 2 3
Leaving, result = 2 3
Leaving, result = 1 2 3
1 2 3

1.6 The Problems Solving Process

Computer science deals with problem solving. There are a number of somewhat formal steps which are used for problem solving. Depending on the size of the problem, some of these steps may not be done separately. Large problems often require teams of workers to solve. In such cases, it may be that some individuals are involved in all steps while others work only on a single step.

1.6.1 Problem Formulation

The algorithms which computer scientists design and study usually are motivated by a problem which needs to be solved. Often the formulation of a problem is key to successful solution of the problem. If the problem is not well undersood or properly formulated, then solution of that problem is more complicated. Sometimes, the solution given is for the wrong problem because the real problem was not properly formulated. We will have more to say about problem formulation later.

1.6.2 Analysis

Systems analysis is a key step in the solution of a problem. This activity is often performed after proper formulation of the problem to be solved. However, the two activities are sometimes related in that analysis of a system may lead to a different understanding of the problem which it turn leads to a refinement of the problem formulation, etc. An outcome of the analysis is some sort document which gives design specifications for solution of the problem.

1.6.3 Design

The design of the solution of a problem usually involves subdividing the problem into an appropriate collection of smaller problems which in turn may be subdivided, etc. Eventually algorithms must be designed or found for each of the sub problems. This design process should follow the design specification produced earlier and the design work should be reviewed periodically to insure that each design meets the design specification. Sometimes, during the design phase, prototypes of all or part of the solution may devised. These prototypes are helpful in providing feedback on the design to the individuals who are paying for the problem solution.

1.6.4 Abstraction

The design phase of a problem solution often requires recognition of problem structure and developing abstractions of that structure. Abstraction plays a key role in handling the solution of large or complex problems.

1.6.5 Experimentation

The individual algorithms which are designed are sometimes implemented so that the behavior of the algorithm may be characterized. This process of experimentation is often an iterative activity. For example, it may be determined experimentally that a particular algorithm is too slow. This may initiate further design work producing a new algorithm which is evaluated experimentally, etc. During experimentation it is necessary to analyze the experimental results and formulate a theory which would explain the results inorder to have a complete understanding of the algorithms being used in the problem solution.

1.6.6 Theory

Analysis of the algorithms used to solve a problem often leads to the development of theories related to the algorithm. On certain kinds of mission critical problems it may be necessary to formally develop these theories, complete with proofs. Often, analysis of an algorithm will lead to an already existing theory which needs only be referenced.

1.6.7 Programming

Eventually, the problem solving process will culminate in an implementation of the solution in some programming languages. The first implementation is sometimes called an alpha version of the system. This program is subjected to testing procedures and user evaluation before a second version of the software is produced (usually called a beta version). The beta software is further tested and evaluated. Problems or bugs are fixed before a release version of the software is produced.

1.6.8 Maintainance

Once a software system has been put into production use it is necessary to provide some sort of on-going maintainance activity which analyzes and repairs user problems and perhaps adds features and updates to the software system.

1.7 Bibliography

[Ive91] Iverson, Kenneth, "J Introduction and Dictionary", Iverson Software, Copyright 1991, 1994, 1995, 1996.