[CSUSB]
>> [CNS]
>> [Comp Sci Dept]
>> [R J Botting]
>> [CSci620]
>>
while
[Source]
In this page we explore the elementary parts prior to a full scale assault on the language using several different methods in later pages. Here it is enough to define the syntax of the language and explore the semantics of its expressions.
Here is a well known algorithm in While:
When x>0, this puts the factorial x into y. When x<=0 it fails to terminate. Ideally our semantics should be able to express both of these meanings.
The first question is how to convert a string like this into a meaningful formal structure. This is the problem of Formal Syntax. I will assume that we have done this already and move directly to expressing the formal structure and its meanings.
1 + 2 * 3into
1 + ( 2 * 3)rather than
(1+2)*3for example.
However we use the same notation for this abstraction as we do in practice to define syntax. However I omit quotation marks around +*-= <= ~ /\ ; if then else while do.
Note: THis omits some useful things like division, modulus, input, output, etc. You can in many cases put it in fairly quickly and easily. Division means you must tackle the question of division by zero however.
Note: We just ignore the syntactic details of priorities etc. and use parentheses as necessary - without putting them in here. If this bothers you, it may help to check that you can rewrite these as tree structures and that work just like the strings we are used to (but with parentheses). This is the tradition in the theory of programming languages. In real language design a lot of effort goes into defining compound statements etc.
As an exercise: you could rewrite the definitions as concrete syntax. This means putting quotes around terminal strings like "+" and "while", fixing ambiguities (like how to parse "1+2+3"), and including rules with parentheses in expressions("2*(3+4)"), and compound statements "{"..."}".
Exercise 1
Take the factorial algorithm in While:
y:=1; while ~(x=1) do ( y:=y*x; x:=x-1)and draw the tree representation of it.
Also, using your experience to provide intuitive semantics, show that if x=4 initially then y=24 after wards.
Exercise 2
Given that x has initial value n and y has value m write a statement in While
that assigns the value of n^m=n*n*n*....*n (m times) to z.
Draw the syntax tree of your statement.
. . . . . . . . . ( end of section Abstract Syntax) <<Contents | Index>>
Semantics of Constants
This version of While uses binary notation to keep it simple. As an exercise you can write the rules for decimal notation if you want.
Also, we will be forced to write negative numbers as arithmetic expressions like this "0-1"! Again this is an interesting exercise to work out how to fix the syntax above and the semantics below.
We use function N to map each Num into a unique Int. To help us to distinguish parts of the while language from pieces of logic and mathematics we write
As a rule, if we have a syntax category Syn and a semantic map S that associates a "meaning" to it from Sem, S:Syn->Sem then we write S<<s>> not S(s).
This will be a general rule... syntactic things are inside << ...>> and the symbol prefixing them indicates the semantic function being applied. This means we can omit quotation marks... instead of
We say that two elements s1 and s2 of Syn are equivalent if they have the same semantics:
So for example
Net
Exercise 3
Show all the steps to evaluate
Extra Exercise
Rewrite the syntax (Num) and (N) so as to allow (1) decimal numbers,
and (2) negative numbers.
Compositional Semantics
A set of equations like those defining N above is said to
be compositional if it mirrors the structure of the abstract syntax.
Firstly each alternative form must have a definition. Second,
the RHS of each equation can only apply the semantic function to
parts of LHS.
Proof Method
We have a Compositional definition of N. This means that the the right hand
sides of each definition is either a "basis element" or when it contains the
function it is applied to parts (not the whole) of the argument on the left
hand side.
Thus we can apply structural induction. Because, implicitly, the Num is the result of a finite number of applications of the the rule that defined Num, and because the definition of N follows the syntax, it means that the parts of the definition are applied only a finite number of times.
Hence, all we have to do is show that a property is
Now every element of Num is one of the above forms, and in each case there is only one rule to apply, and in each case it produces a single answer.
. . . . . . . . . ( end of section Proof of Theorem 4) <<Contents | Index>>
. . . . . . . . . ( end of section N is well defined) <<Contents | Index>>
Equivalence of Numbers
You can show that N is a one-one map and so two constants are equivalent
precisely when they are identical in this simple language
. . . . . . . . . ( end of section Semantics of Constants) <<Contents | Index>>
Notice that we usually omit the parenthsis so that if s: State and x: Var, then s x = s(x).
So for s:State, x:Var, s x= 3 iff the value of x in s is 3.
We can write states as a list of variable+>value pairs. For example
So
Let
Note: in languages where variables are declared we have to make the State more complex.
Updating a State by Changing a Variable
The update operation on states is defined by
is written [y+>v] for a variable y and and a value (Int) v.
For s:State, x:Var, v:Int , s[y+>v] :: State, where
Net
As a result:
We can express complex state changes by listing a series of these update operations. So for any state s, variables x and y, and constants a and b: s[x+>a][y+>b] ::= (s[x+>a])[y+>b].
Fact: if there are several updates.... we only need the last one:
For example if s is a state, x and y are different variables and a and b
constant values then
Net
We will use this notation to define the semantics of assignment statements later.
. . . . . . . . . ( end of section Semantics of Variables) <<Contents | Index>>
Here is the formal definition:
Definition of Semantic map A
Note: the +*- on the LHS, inside <<...>> is a character. But on the RHS they become the normal arithmetic operations.
. . . . . . . . . ( end of section Definition of Semantic map A) <<Contents | Index>>
Recall: the +*- symbols on the LHS of an equation (inside <<...>>) are syntactic characters. On the RHS they are operations on integers.
Notice that the definition of A is compositional. Every syntactic form is defined in terms of its components.
Example 5
What is A<<x+1>> s when s x=3.
Net
Notice that we did not have to define anything but s x to work out the value of x+1. Clearly this is an important property of the meaning of an expression in a clear programming language: It's value should not depend on variables that are not in the expression.
Example 6
Consider two approaches to adding a unary negation operator to the While
language. If we define, for all expressins a:
The above is not compositional (and proofs become harder as a result). Instead we prefer to write
Of course they both lead to the same values under all circumstances in this case... but in general departing from compositional definitions can lead to meaningless (or difficult to handle) definitions.
Exercise 7
Prove that equations do give a well defined function A:Aexp->(State- >Int ).
In other words show that for each a:Aexp, s:State, there is only one i:Int with A<<a>> s=i. Use structural induction to do this.
Hint: How did we do the second step for N?
Equivalence of Arithmetic Expressions
Two arithmetic expressions b1,b2:Aexp are equivalent if they have the same semantics:
Note. Here we compare two functions State->Int for equality. Two functions are equal when they have the same domain and co-domain and the equal values for all arguments. So in this case, two expressions are equivalent if they always have the same values in every state:
. . . . . . . . . ( end of section Semantics of Expressions) <<Contents | Index>>
Semantics of Boolean Expressions
Here we define B:Bexp->(State->{tt,ff}) where tt and ff stand for true or false respectively. Notice that all that matters is that these are two different things. Think of them as enumerated data types in Pascal, Ada, C, or ML. However we don't go as far as C and muddle up tt and ff with 0 and 1!
. . . . . . . . . ( end of section Definition of Semantic Map B) <<Contents | Index>>
Exercise 8
Assume that s x = 3, determine B<< ~(x=1) >> s.
Exercise 9
Prove that the Definition of Semantic Map B above defines a well defined
function: Bexp->(State->{tt,ff}).
Equivalence of Boolean Expressions
As above two boolean expressions b1,b2:Bexp are equivalent if they always have the same values in every possible state:
For b1,b2:Bexp, b1 equivalent b2 iff (for all s:State( B<<b1>>s=B<<b2>> s )).
( b1=>b2 should stand for b1 implies b2 in the sense of symbolic logic, and
Give compositional definitions for the semantics of Bexpp.
Same power
Prove that for every b1:Bexpp, there is at least one b2:Bexp such that b1
equivalent b2.
. . . . . . . . . ( end of section Exercise 10) <<Contents | Index>>
. . . . . . . . . ( end of section Semantics of Boolean Expressions) <<Contents | Index>>
There are two key properties of expressions that we will need later. First the value of an expression does not depend on the variables that are not in it. Second a change in a variable that occurs in an expression is reflected by a similar change inside an expression where it occurs. To express these we need some more formally defined ideas: Free Variables and Substitution.
Free Variables
Associated with any expression are the variables that appear in that
expression. These are called free variables (there are also bound variables
in more complex expressions, but they do not appear in our Aexp and Bexp). We
formulate this as the map FV below:
Quick Exercise
Is the above definition compositional? Why/Why not?
Lemma 11
Let s1 and s2 be two states and a an arithmetic expression.
For two States s1, and s2, if for all x:FV(a), s1 x = s2 x then A<<a>> s1 = A<<a>> s2.
Extra Exercise
Define FV for Boolean Expressions
Exercise 12 (Essential)
Using your definitions show that this is true.
Let s1 and s2 be two states and b an Boolean expression.
If for all x:FV(b), s1 x = s2 x, then B<<b>> s1 = B<<b>> s2.
Substitution
.Dangerous_Bend
There is a serious abuse of notation coming up. Fasten seat belts, put your
analyst on danger money, and relax.
We (like all good books on logic, meta-mathematics, symbolic processing, AI and LISP) need to define and study the effect of changing an expression a by taking a variable y in a and replacing it by another expression a0.
a[y+>a0]::Aexp=Result of replacing all y in a by a0.
Net
But for all states s: A<<(x+1)[x+>3]>> s = 4.
Indeed: substitution and assignment can have similar effects
Another example
(Again no simplification!)
S2
Let s1=[x+>1, y+>2, z+>3] and s2=[x+>5, y+>2, z+>3], show that
S3
Let s1=[x+>1, y+>2, z+>3], s2=[x+>1, y+>2, z+>4], and
. . . . . . . . . ( end of section Quick Substitution Exercises) <<Contents | Index>>
Exercise 13
Prove that for all s1,s2,a,y,a0,...
Exercise 14
Define substitution for boolean expressions (Bexp):
For b:Bexp, y:Var, a:Aexp, b[y+>a]::Bexp=result of replacing y by a0 throughout.
Prove that your definition satisfies
. . . . . . . . . ( end of section Properties of A and B) <<Contents | Index>>
We do this by defining a map D that maps each Stm in to a change of State:
This implies that D<<S>> is a partial map, indicated with a '<>->' arrow.
The above depends on the following definition:
Notes on D
The definition of D <<x:=a >> implies that if x=y then D <<x:=a >> s y = A <<a >> s
but if not x=y then D <<x:=a >> s y = s y. Similarly for all variables x,
D <<skip >> s x = s x.
The ";" rule defines a unique successor state if and only if both component are defined. Also note that the order of S1 and S2 are reversed on opposite sides of the definition.
The rule for while b do S is a natural rule and can be used to derive the meaning of a program that terminates. For example consider
Let s = [x+>3], then
Net
The above definition can be used but is not compositional. The equation for while defines the meaning D << while b do S >> in terms of D << while b do S >>. So, if there is a non-terminating loop, then semantic equations, themselves, tend to not terminate!
If one tried the deraivation above with s = [x+> (-3)] for example, we keep generating new formulae, for ever. As a result it is not clear if a program containing a while is well-defined or not. It took Scott and Strachey's theory to fix this problem. They invented their theory of Domains, complete partial orders, and lattices etc. so that we would have a compositional semantics. They develope a abstract and elegant theory of the kinds of functions that are the meanings of programs. For this more complex Direct Denotational Semantics see [ denotational.html ] and [ fixed.html ] (under development).
. . . . . . . . . ( end of section Semantics of Statements) <<Contents | Index>>
. . . . . . . . . ( end of section The Language While) <<Contents | Index>>
Glossary