CSE 111, Fall 2000

Great Ideas in Computer Science

Lecture Notes #36


1.  Computer Science as Algorithmic Problem Solving

a)    An algorithm for a problem is a procedure
        (i.e., a set of instructions) for solving the
        problem that is unambiguous and "effective"
        (where "effective" means:  the procedure halts
        and it outputs the correct answer).

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.

2.  Four (!) Great Insights of Computer Science

a)    All the information about any computable
        problem can be represented using only 2 nouns:
        0, 1.

        *    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

        *    sequence


        *    selection (or "choice")

                if <test>
                    then S1
                    else S2

        *    repetition (or "while-loop")

                while <test> do

        (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).

3.  Models of Computation

a)    Karel the Robot (a generalized version of a TM)

        *    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>)
                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:


                    I/P:    <str> + <str>
                    O/P:    <str>


    substr(<str>, <starting-integer>, <length-integer>)
                    O/P:    substring of <str> that begins
                              at <starting-integer> and has
                               length <length-integer>


                  I/P:    length(<str>)
                  O/P:    integer representing <str>'s length


                    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

            The Memory contains registers ("memory
            locations") for storing both programs and

        *    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.

4.    Other Topics

a)    Decision Trees:
            An application of selection.
            If-then-else instructions allow a program
                to behave differently in different situations

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

            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)


Copyright © 2000 by William J. Rapaport (rapaport@cse.buffalo.edu)

file: 111F00/lecturenotes36.08dc00.html