CSCI 431 Lecture Notes - Semantics
Informal Semantics
- Grammars can be used to define the legal programs of a language,
but not what they do! (Actually, most languages place further,
non-grammatical restrictions on legal programs, e.g.,
type-correctness.)
- Language behavior is usually described, documented, and
implemented on the basis of natural-language (e.g., English)
descriptions.
- Descriptions are usually structured around the language's
grammar, e.g., they describe what each nonterminal does.
- Natural-language descriptions tend to be imprecise, incomplete,
and inconsistent.
Example: FORTRAN DO-loops.
``DO n i = m1, m2, m3
Repeat execution through statement n, beginning with i = m1,
incrementing by m3, while i is less than or equal to m2. If
m3 is omitted, it is assumed to be 1. m's and i's cannot be
subscripted. m's can be either integer numbers or integer variables;
i is an integer variable.''
-- from DEC Fortran-II Manual, 1974.
Consider:
DO 100 I = 10, 9, 1
...
100 CONTINUE
How many times is the body executed?
How about this example in Pascal?
I := 1
J := 2 ;
while (I < J) do
begin
I := I+1 ;
J := J+1 ;
end
In the early days
- In the early days, we were often imprecise.
- One solution: it's however the compiler on the S/360 in
Poughkeepsie does it...
- To understand PL/I, you must understand S/360 assembler language
... Not an improvement
- Also, maybe this is too precise
- should the result be the same on 32 and 64 bit machines?
- should people depend on weird machine dependencies
- what if there is a bug in the compiler?
- In summary experimental semantics is:
- difficult to understand
- awkward to use
- subject to accidental change
- wholly non-portable
Formal Semantics
- Aims: Rigorous and unambiguous definition in terms of a
well-understood formalism, e.g., logic, naive set theory, etc.
- Independence from implementation. Definition should describe how
the language behaves as abstractly as possible.
- Uses:
- Provably-correct implementations.
- Provably-correct programs.
- Basis for language comparison.
- Basis for language design.
(But usually not basis for learning a language.)
- Various Semantic Models:
- Axiomatic - Hoare, 1969
- Operational
- Denotational
- Each has different purposes and strengths.
Semantic Models
- Programs are built out of commands like assignment, conditionals,
etc.
- The action of a program is to map from an acceptable initial state
to an acceptable final state
- A formal model can be used as the basis for rigorous
discussion
- The rules used are described and followed very precisely
VDL -- Vienna Definition Language
- An implementation of operational semantics from the 1970's
- To define PL/I, show how to translate it into VDL
- It defines how the programming language is implemented on a
virtual machine
- The changes that occur in the machine's state when it executes a
given statement define the meaning of that statement.
- Basically, you get a 400-page unreadable definition
Axiomatic Semantics
Notation
- Conditions on the program variables are written using standard
mathematical notations together with logical operators like:
- ^ (and), | (or), ~ (not), => (implies)
- Hoare's original notation was P {S} Q not {P} S {Q}, but the later
is more frequently used
The Basic Idea
- {P} S {Q} is true if
- whenever S is executed in a state satisfying P
- and if the execution of S terminates
- then the state in which S terminates satisfies Q
Example: {X=1} X:=X+1 {X=2}
- P is the condition that the value of X is 1
- Q is the condition that the value of X is 2
- S is the assignment command X:=X+1
- {X=1} X:=X+1 {X=2} is clearly true
Formal Specification
Example: I want a program that swaps the values in X and Y
- {X=x ^ Y=y} S {X=y ^ Y=x}
- The statement sequence: BEGIN R:=X; X:=Y; Y:=R; END would fulfill
the specification
- The statement sequence: BEGIN X:=Y; Y:=X; END would not
fulfill the specification
How do we determine when the program fulfills the specification?
A formal Proof
- A proof consists of a sequence of lines
- Each line is an instance of an axiom, or follows from the
previous lines by a rule of inference
- An example proof for the statement: (X+1)2 =
X2 + 2 * X + 1
1. (X+1)2 = (X+1) * (X+1) definition of ()2
2. (X + 1) * (X + 1) = (X+1) * X + (X+1) * 1 distributive law
3. (X+1)2 = (X+1) * X + (X+1) * 1 substituting 2 into 1
4. (X+1) * 1 = (X+1) identity law
5. (X+1) * X = X * X + 1 * X distributive law
6. (X+1)2 = X * X + 1 * X + X + 1 substituting 4 and 5 into 3
7. 1 * X = X identity law
8. (X+1)2 = X * X + X + X + 1 substituting 7 into 6
9. X * X = X2 definition of ()2
10. X + X = 2 * X 2 = 1 + 1, distributive law
11. (X+1)2 = X2 + 2 * X + 1 substituting 9 and 10 into 8
Weakest preconditions
- In proving the correctness of a program, it is often easiest to
work by computing preconditions from the given postconditions:
{?} SUM := 2 * X + 1 {SUM > 1}
- In this way we can work from the desired postcondition at program
termination back to the stated precondition to formulate a proof of
program correctness
- The weakest preconditions is the least restrictive
precondition that will guarantee the validity of the associated
postcondition.
- For example, in the statement above, {X > 10}, {X > 50}, and
{X > 100 & Y > 0}, are all valid preconditions, but the weakest of
all preconditions is {X > 10}.
- Examples:
{ X = 5 } X := X+5 { X = 10 }
{ X = Z+3 } X := X+5 { X=Z+8 }
{ X = 5 & Y = 13 } X := X+5 { X=10 }
{ true } X := Y { X = Y }
{ 5 = 6 & X = 5 } X := 6 { X = 5 }
{ false } statement { P }
law of the excluded miracle
if 4 = 7, then I am the pope
{ ? } X := Y + 3 { X = 5 }
{ ? } if X = 0 then Y := 5 { Y = 5 }
{ ? } while X < Y do X := X + 1 { X = Y }
{ ? } X := X + X { X = 10 }
Assignment Statements
Selection statements
Loop invariants