Professional Documents
Culture Documents
Describing The Meanings of Programs - PPL
Describing The Meanings of Programs - PPL
Behavior: What actions the program takes and in what order. For example, it
might read input; perform calculations, and output results.
State Changes: How the program modifies its internal state as it runs. This
includes changes to variables, data structures, and other program elements.
Interactions: How the program interacts with external systems or users. This
could involve reading from or writing to files, communicating over a network, or
responding to user input.
Effects: The overall impact of running the program, such as producing output,
modifying data, or causing side effects.
Dynamic semantics:
At the highest level, the interest is in the final result of the execution of a
complete program. This is sometimes called natural operational semantics.
At the lowest level, operational semantics can be used to determine the precise
meaning of a program through an examination of the complete sequence of
state changes that occur when the program is executed.
Example
int main() {
int a = 5;
int b = 7;
int sum = a + b;
print(sum);
return 0;}
The operational semantics by executing this compiled program on a computer:
1. Assign Values: The first step is to allocate memory for variables a, b, and
sum and assign them their initial values: a = 5, b = 7.
3. Print Result: After calculating the sum, the program prints the value of sum,
which is 12.
Denotational semantics
Denotational semantics provides a rigorous and widely accepted formal method for
describing the meaning of programs. It is grounded in recursive function theory,
which enables precise definitions of programming language constructs and
their meanings.
Add(x,y) = x + y
Here, the function add takes two numbers x and y as inputs (the syntactic domain)
and returns their sum as the output (the semantic domain).
The main idea behind denotational semantics is that mathematical objects provide
a rigorous way to model the meaning of programming language constructs. Unlike
operational semantics, denotational semantics does not focus on the step-by-step
execution of programs but rather on establishing mathematical relationships
between language constructs and their meanings.
In denotational semantics, mapping functions play a important role. Just like any
mathematical function, they have a domain and a range.
Domain: The domain consists of all the valid inputs (or parameters) for the
function. In denotational semantics, this domain is referred to as the
syntactic domain because it represents the syntactic structures of the
programming language being mapped.
Range: The range comprises the resulting objects to which the parameters
are mapped. This range is known as the semantic domain in denotational
semantics because it represents the meaning or semantics assigned to the
syntactic structures.
Example:
Consider a simple programming language that has a construct for adding two
numbers together, written as add(x, y). In denotational semantics, we can define a
mapping function for this construct.
Domain (Syntactic Domain): The parameters x and y are the valid inputs to
our mapping function. They represent the syntactic structures of our
programming language.
Domain: The syntactic domain consists of pairs of numbers, (x, y), where x
and y are valid numerical values in our programming language.
Axiomatic semantics
For example, if we have a statement like "x = x + 1" in our program, in axiomatic
semantics, we'd set a rule like "{ x > 0 } x = x + 1 { x > 1 }".
This means if x starts as a number greater than 0, after running the statement, it
will be greater than 1.
These rules help us understand how each part of the program affects the data it
works with.