Read Understanding Computation Online

Authors: Tom Stuart

Tags: #COMPUTERS / Programming / General

Understanding Computation (58 page)

BOOK: Understanding Computation
2.34Mb size Format: txt, pdf, ePub
ads
Applications

This chapter has sketched the basic idea of
abstract interpretation—using cheap approximations to learn
about the behavior of expensive computations—and showed a simple type
system as an example of how approximations can be useful for analyzing
programs.

Our discussion of abstract interpretation was very informal.
Formally, abstract interpretation is a mathematical technique where
different semantics for the same language are connected together by
functions that convert collections of concrete values into abstract ones
and vice versa, allowing the results and properties of abstract programs
to be understood in terms of concrete ones.

A notable industrial application of this technique
is the
Astrée
static analyzer
, which uses abstract interpretation to
automatically prove that a C program is free of runtime errors like division by zero,
out-of-bounds array indexing, and integer overflow.
Astrée
has been used to verify the flight control software of Airbus A340 and
A380 airplanes, as well as the automatic docking software for the
Jules
Verne
ATV-001 mission that transported supplies to the International Space
Station. Abstract interpretation respects Rice’s theorem
by providing safe approximations rather than guaranteed answers, so
Astrée
has the potential to report a possible runtime error
where none actually exists (a
false alarm
); in practice, its
abstractions were precise enough to avoid any false alarms when verifying the A340
software.

Programs written in the
Simple
language can only
manipulate rudimentary values—numbers and Booleans—so the types seen in this chapter are very
basic. Real programming languages handle a wider variety of possible values, so real static
type systems are more sophisticated. For example, statically typed functional programming
languages like ML and Haskell have values that are functions (like Ruby’s procs), so their
type systems support
function types
with meanings like “a function that
takes two numeric arguments and returns a Boolean,” allowing the type checker to verify that
the arguments used in a function call match up with that function’s definition.

Type systems can carry other information too: Java has a
type and effect system
that tracks not only the
types of methods’ arguments and return values but also which
checked exceptions
can be thrown by the body of the
method (throwing an exception is an
effect
), which
is used to ensure that all possible exceptions are either handled or
explicitly propagated.

[
85
]
“Sufficiently powerful” means “universal” here. See
Universal Systems Can Loop Forever
for more.

[
86
]
A number’s
absolute value
is what we get when we take the
sign away. The absolute value of −10, for example, is 10.

[
87
]
Ruby’s
Bignum
objects can
represent integers of any size, limited only by available
memory.

[
88
]
Unlike, say, Smalltalk.

[
89
]
An easy solution would be to say that the type system rejects a statement unless all
of its execution paths produce the same context.

[
90
]
In this case, the detail is that the type of
x
depends upon the value of
b
. Our types don’t contain
any information about the specific values of variables, and they can’t express
dependencies between types and values.

Appendix A. Afterword

Well, that’s the end of our journey through the theory of computation. We’ve designed languages and machines with various capabilities, teased computation out of unusual systems, and crashed headlong into the theoretical limits of computer programming.

Aside from exploring specific machines and techniques, we’ve seen some more general ideas along the way:

  • Anyone can design and implement a programming language. The basic ideas of syntax and semantics are simple, and tools like Treetop can take care of the uninteresting details.

  • Every computer program is a mathematical object. Syntactically a program is just a large number; semantically it can represent a mathematical function, or a hierarchical structure which can be manipulated by formal reduction rules. This means that many techniques and results from mathematics, like Kleene’s recursion theorem or Gödel’s incompleteness theorem, can equally be applied to programs.

  • Computation, which we initially described as just “what a computer does,” has turned out to be something of a force of nature. It’s tempting to think of computation as a sophisticated human invention that can only be performed by specially-designed systems with many complicated parts, but it also shows up in systems that don’t seem complex enough to support it. So computation isn’t a sterile, artificial process that only happens inside a microprocessor, but rather a pervasive phenomenon that crops up in many different places and in many different ways.

  • Computation is not all-or-nothing. Different machines have different amounts of computational power, giving us a continuum of usefulness: DFAs and NFAs have limited capabilities, DPDAs are more powerful, NPDAs more powerful still, and Turing machines are the most powerful we know of.

  • Encodings and levels of abstraction are essential to harnessing the power of computation. Computers are machines for maintaining a tower of abstractions, beginning at the very low level of semiconductor physics and rising to the much higher level of multitouch graphical user interfaces. To make computation useful, we need to be able to encode complex ideas from the real world in a simpler form that machines can manipulate, and then be able to decode the results back into a meaningful high-level representation.

  • There are limits to what computation can do. We don’t know how to build a computer that is fundamentally more capable than a Turing machine, but there are well-defined problems that a Turing machine can’t solve, and a lot of those problems involve discovering information about the programs we write. We can cope with these limitations by learning to make use of vague or incomplete answers to questions about our programs’ behavior.

These ideas may not immediately change the way you work, but I hope they’ve satisfied some of your curiosity, and that they’ll help you to enjoy the time you spend making computation happen in the universe.

Index
A note on the digital index

A link in an index entry is displayed as the section title in which that entry appears. Because some sections have multiple index markers, it is not unusual for an entry to have several links to the same section. Clicking on any link will take you directly to the place in the text in which the marker appears.

Symbols
* operator,
Variadic Methods
,
Syntax
. (dot),
Data Structures
,
Objects and Methods
: (colon),
Basic Data
=> prompt,
Interactive Ruby Shell
>> prompt,
Interactive Ruby Shell
[ ] (square brackets),
Data Structures
,
Procs
{ } (curly brackets),
Data Structures
,
Blocks
A
absolute value,
Abstraction: Multiplying Signs
abstract interpretation
about,
Abstract Interpretation
adding signs,
Safety and Approximation: Adding Signs

Safety and Approximation: Adding Signs
applications,
Applications
multiplying signs,
Abstraction: Multiplying Signs

Abstraction: Multiplying Signs
route planning,
Route Planning
abstract machines,
Operational Semantics
abstract syntax tree (AST)
about,
Syntax
building by hand,
Expressions
reduction relation,
Small-Step Semantics
accept states,
Output
,
Nondeterminism
,
Semantics
Adams, Douglas,
Universal Systems Can Loop Forever
algorithms,
Universal Systems Can Perform Algorithms

Universal Systems Can Perform Algorithms
Analytical Engine,
Finding Meaning
applications
abstract interpretation,
Applications
big-step semantics,
Applications
denotational semantics,
Applications
small-step semantics,
Applications
arguments
blocks of code and,
Blocks
messages and,
Objects and Methods
passing to methods,
Expressions
procs and,
Arguments
variable number of,
Variadic Methods
Array class
#<< method,
Alternatives
about,
Enumerable
#push method,
Strings
assignment statements,
Statements
assignments
local variables and,
Local Variables and Assignment
parallel,
Local Variables and Assignment
,
Variadic Methods
AST (abstract syntax tree)
about,
Syntax
building by hand,
Expressions
reduction relation,
Small-Step Semantics
Astrée static analyzer,
Applications
axiomatic semantics,
Alternatives
B
Babbage, Charles,
Finding Meaning
balanced brackets example,
Just Add Power

Just Add Power
big-step semantics
about,
Big-Step Semantics
applications,
Applications
comparing styles,
Statements
expressions,
Expressions

Expressions
statements,
Statements

Statements
Bignum object,
Abstraction: Multiplying Signs
binary representation,
Encoding
blocks of code
about,
Blocks
arguments and,
Blocks
Booleans in FizzBuzz example,
Booleans

Booleans
Brzozowski’s algorithm,
Equivalence
C
call stacks,
Statements
,
Just Add Power
case expression,
Control Flow
,
Expressions
CFG (context-free grammar),
Decidability
Chapman, Paul,
Conway’s Game of Life
Chomsky normal form,
Decidability
Church encoding,
Numbers
Church numerals,
Numbers
Church, Alonzo,
Numbers
Church–Turing thesis,
Universal Systems Can Perform Algorithms
,
Decidability
classes
constants and,
Defining Constants
inheritance and,
Classes and Modules
instances and,
Classes and Modules
,
Expressions
methods and,
Classes and Modules
,
Classes and Modules
,
Monkey Patching
colon (:),
Basic Data
combinators (SKI combinator calculus),
SKI Combinator Calculus

Iota
comma-separated values,
Data Structures
compilers, denotational semantics and,
Applications
computational irreducibility,
Depressing Implications
computing machines
about,
The Simplest Computers
abstract,
Operational Semantics
computing power,
Just Add Power

Just Add Power
,
How Much Power?
,
Maximum Power

Multidimensional Tape
deterministic finite automata,
Deterministic Finite Automata

Simulation
deterministic pushdown automaton,
Deterministic Pushdown Automata

Simulation
equivalence,
Equivalence

Equivalence
general-purpose,
General-Purpose Machines

Simulation
,
Universal Systems Can Loop Forever
nondeterministic finite automata,
Nondeterministic Finite Automata

Free Moves
nondeterministic pushdown automaton,
Nondeterministic Pushdown Automata

Nonequivalence
nondeterministic Turing machines,
Nondeterministic Turing Machines
parsing with PDA,
Parsing with Pushdown Automata

Practicalities
regular expressions,
Regular Expressions

Parsing
virtual,
Expressions
computing power (see power (computing))
concatenating
regular expressions,
Semantics
strings,
Expressions
,
Syntax
conditional statements
about,
Statements
Booleans and,
Booleans

Booleans
constants
about,
Defining Constants
classes and,
Defining Constants
defining,
Defining Constants
lambda calculus and,
Impersonating the Lambda Calculus
removing,
Removing Constants
context-free grammar (CFG),
Decidability
control flow in Ruby,
Control Flow
converting
NFA to DFA,
Equivalence

Equivalence
NFA to regular expressions,
Just Add Power
Conway, John,
Conway’s Game of Life

Conway’s Game of Life
Cook, Matthew,
Tag Systems
correctness, small-step semantics,
Correctness
curly brackets { },
Data Structures
,
Blocks
current object,
Objects and Methods
cyclic tag systems,
Cyclic Tag Systems

Cyclic Tag Systems
D
data structures
comma-separated values,
Data Structures
hashes,
Data Structures
pairs,
Pairs
range of values,
Data Structures
square brackets for,
Data Structures
decision problems,
Decidability

Decidability
def keyword,
Objects and Methods
denotational semantics
about,
Denotational Semantics
applications,
Applications
comparing styles,
Statements
compilers and,
Applications
expressions,
Expressions

Expressions
statements,
Statements

Statements
determinism
deterministic finite automata,
Determinism
deterministic pushdown automaton,
Determinism
deterministic Turing machines,
Determinism
deterministic finite automata (see DFA)
deterministic pushdown automaton (see DPDA)
deterministic Turing machines (see DTM)
DFA (deterministic finite automata)
about,
Deterministic Finite Automata
converting from NFA,
Equivalence

Equivalence
determinism,
Determinism
input,
States, Rules, and Input
mimization,
Equivalence
output,
Output

Output
processor,
Output
rules,
States, Rules, and Input
simulation,
Simulation
states,
States, Rules, and Input
storage,
Output
Turing machines and,
General-Purpose Machines
domain theory,
Formality
dot (.),
Data Structures
,
Objects and Methods
DPDA (deterministic pushdown automaton)
about,
Storage
determinism,
Determinism
rules,
Rules
simulation,
Simulation

Simulation
storage,
Storage
DTM (deterministic Turing machines)
about,
Deterministic Turing Machines
determinism,
Determinism
rules,
Rules
storage,
Storage

Storage
dynamic semantics,
Correctness
,
Static Semantics
E
encoding
about,
Encoding
Church,
Numbers
Enumerable module
about,
Enumerable
#detect method,
Simulation
,
Infinite streams
#first method,
Infinite streams
#flat_map method,
Enumerable
#inject method,
Lists
#map method,
Infinite streams
#select method,
Infinite streams
#take method,
Infinite streams
Enumerator class,
Infinite streams
Enumerator::Lazy class,
Infinite streams
equality method (#==),
Struct
equality, extensional,
Equality
Euclid’s algorithm,
Universal Systems Can Perform Algorithms

Universal Systems Can Perform Algorithms
expressions
about,
Expressions
big-step semantics,
Expressions

Expressions
denotational semantics,
Expressions

Expressions
reducing,
Reducing expressions

Reducing expressions
,
SKI Combinator Calculus
regular,
Regular Expressions

Parsing
replacing variables in,
Replacing variables

Replacing variables
SKI combinator calculus and,
SKI Combinator Calculus
small-step semantics,
Expressions

Expressions
extensional equality,
Equality
external memory (see TM)
F
Faber and Faber publisher,
Too good to be true
finite automata
deterministic,
Deterministic Finite Automata

Simulation
nondeterministic,
Nondeterministic Finite Automata

Free Moves
regular expressions,
Regular Expressions

Parsing
structural overview,
States, Rules, and Input
finite state machines (see DFA)
fixed-point semantics (see denotational semantics)
FizzBuzz program
about,
The Problem
avoiding arbitrary recursion,
Avoiding arbitrary recursion

Avoiding arbitrary recursion
implementing Booleans,
Booleans

Booleans
implementing lambda calculus,
Implementing the Lambda Calculus

Parsing
implementing lists,
Lists

Lists
implementing numbers,
Numbers

Numbers
implementing numeric operations,
Numeric Operations

Numeric Operations
implementing pairs,
Pairs
implementing predicates,
Predicates
implementing strings,
Strings
infinite streams,
Infinite streams

Infinite streams
problem,
The Problem
solution,
The Solution

The Solution
formal semantics
about,
The Meaning of “Meaning”
,
Formal Semantics in Practice
finding meaning,
Finding Meaning
formality,
Formality
free moves feature,
Free Moves

Free Moves
function calls,
Calling functions
BOOK: Understanding Computation
2.34Mb size Format: txt, pdf, ePub
ads

Other books

Lethal by Sandra Brown
A Station In Life by Smiley, James
Italian Passion by Jayne Castel
Freakshow by Jaden Wilkes
Hauntings and Heists by Dan Poblocki
Kiss of the Silver Wolf by Sharon Buchbinder
Taste of Candy by Evers, Shoshanna
Flashback by Amanda Carpenter