b) A problem is computable just in case there is
an algorithm (expressed
as a computer
program written in some
programming
language) that solves the
problem.
* This
led us into a discussion of the binary
system, and how to represent (or code)
letters and symbols into decimal numerals,
how to code decimal numerals as binary
numerals, and how to decode binary
numerals into decimal.
b) Turing's insight:
Every algorithm can be expressed
using only
5 verbs (for a Turing machine,
i.e., a model
of computation that considers
an infinite
tape, divided into squares,
with only "0" or "1"
(or nothing) written on
each square, and a
reader/printer that can
only look at one square
at a time, but that can
move back and forth to
different squares):
* move
right
* move
left
* print
"1"
* print
"0"
* erase
c) (i) Boehm & Jacopini's insight:
Only 3 grammar rules are
needed to combine
any set of basic instructions
into more complex
instructions:
* sequence
begin
S1;
S2
end
* selection (or "choice")
if <test>
then S1
else S2
* repetition (or "while-loop")
while <test> do
S
(where <test> is a "Boolean" test,
i.e., a statement that is
either true or false).
(ii) There is also a 4th useful grammar rule:
New instructions can be defined using
the basic instructions combined by the
grammar rules, and then this new
instruction can be given a name.
*
e.g., Karel's "define-new-instruction"
* e.g., Pascal's "function" declarations
d) The Church-Turing Thesis:
A problem is computable
just in case there
is a Turing-machine program
that can solve it.
It follows from this and
Boehm/Jacopini's
insight that all programming
languages are
equally powerful.
However, some are better
for expressing and solving
some problems than
others (the same is true
about natural languages:
you can say the same things
in any natural
language, but sometimes
it's easier in one
language rather than another).
* Karel
"lives" in a 2-dimensional world
* that
has walls and beepers
* and
Karel can perform 5 basic actions:
- move
- turnleft
- pickbeeper
- putbeeper
- turnoff
* that
can be combined by sequence,
selection, and repetition (which comes
in 2 varieties: while and iterate), and
that can be given new names.
* both
selection and repetition require
Karel to be able to perform several
perceptual tests about the presence
or absence of walls and beepers.
b) Pascal
* basic actions:
I/P: readln(<memloc>)
O/P: writeln(<memloc>)
or:
writeln(<string>)
or:
writeln(<integer>)
assignment: <memloc> := <value>
where the <value> is either
given directly:
e.g., x := 5, s := 'jello'
or has to be computed:
e.g., x := 2+3,
s := 'jel' + 'lo',
or s := substr('jelly',1,3)+substr('hello',4,2)
* data types:
we looked at only 2: strings, integers
where strings were implemented as
"varying [n] of char"
* operations on strings:
concatenation:
I/P: <str> + <str>
O/P: <str>
substring:
I/P:
substr(<str>, <starting-integer>, <length-integer>)
O/P: substring of <str> that begins
at <starting-integer> and has
length <length-integer>
length:
I/P: length(<str>)
O/P: integer representing <str>'s length
index:
I/P: index(<str>, <substring>)
O/P: integer representing <substring>'s
location in <str>
* operations on integers:
+, -, *, div, mod
* relations on integers (or strings, for that
matter!)
(for use in Boolean tests):
=, <>, <, <=, >, >=
c) Assembly Language (for the P88 computer):
* P88 simulated computer:
We used a real computer (the one in
class, or those in the Cybraries, or yours
at home) to simulate a "toy" computer,
called the P88. Note that the P88, by
the Church-Turing Thesis and the Boehm/
Jacopini insight, is just as powerful as the
real computer that it is simulated on!!
P88
consists of a CPU (central processing unit)
and Memory.
The CPU contains 4 registers:
- an Instruction Pointer that points to
the next instruction to be fetched
- an Instruction Register that contains
the current instruction being executed
- a Condition Flag for storing the
result of comparisons
- an Accumulator (AX) for doing
computations.
The
Memory contains registers ("memory
locations") for storing both programs and
data.
* The assembly
language is a programming
language for moving information between
the CPU and the Memory, and for doing
computations and I/O:
copy ax, m
copy m, ax these move info between
the CPU and Memory
in ax
out ax
these do I/P and O/P,
always from the AX
cmp ax, m compares contents of AX
with contents of a memloc
jb label
jnb label these cause control
of the
program to jump to the
instruction at the "label"
depending on the result
of the comparison, which
is either a "B" or an "NB"
stored in the CF; this is
how selection and repetition
are implemented
jmp label unconditional jump
to
the instruction at the "label"
halt ends the fetch cycle.
* All higher-level
programs in languages
like Pascal (or C++, or Java, etc.) are
"compiled", i.e., translated, into
machine-language programs (written
entirely in 0s and 1s).
* Assembly-language
programs are simply
machine-language programs that are
readable by humans.
b) Top-Down Design and Stepwise Refinement:
A
method for solving problems by splitting
them into smaller subproblems, each of
which is easier than the big problem,
and then solving each of the smaller & easier
subproblems by means of top-down design
and stepwise refinement, until you reach a
smallest and easiest subproblem that is so
easy to solve, it can be done by a basic
instruction.
Motto: "Always
put off till later what you
don't want to handle today"
(Think
of The Cat in the Hat Comes Back,
for those of you familiar with it :-)
c) Text Processing:
An application of strings.
Computation (and mathematics,
for that matter)
is not just number manipulation!
d) Artificial Intelligence:
Is
cognition/thinking computable?
Turing Test = a behavioral test of whether
something (e.g., a computer)
can think.
(Answer: It can if it can convince you that
it can!)
(Chinese-Room
reply to the Turing Test:
Just convincing you that it can think
doesn't mean that it can really think)