Denotational Semantics of a Simple Imperative Language Using Intensional Logic

Similar documents
Programming Languages Third Edition

An Annotated Language

Note that in this definition, n + m denotes the syntactic expression with three symbols n, +, and m, not to the number that is the sum of n and m.

The Formal Semantics of Programming Languages An Introduction. Glynn Winskel. The MIT Press Cambridge, Massachusetts London, England

Chapter 3. Semantics. Topics. Introduction. Introduction. Introduction. Introduction

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Hoare Logic. COMP2600 Formal Methods for Software Engineering. Rajeev Goré

Assignment Calculus: A Pure Imperative Language

Hoare logic. A proof system for separation logic. Introduction. Separation logic

Introduction to Axiomatic Semantics

Contents. Chapter 1 SPECIFYING SYNTAX 1

Concepts of programming languages

Hoare Logic and Model Checking

axiomatic semantics involving logical rules for deriving relations between preconditions and postconditions.

Semantics of programming languages

This is already grossly inconvenient in present formalisms. Why do we want to make this convenient? GENERAL GOALS

Hoare logic. WHILE p, a language with pointers. Introduction. Syntax of WHILE p. Lecture 5: Introduction to separation logic

Semantics of programming languages

Lecture 5 - Axiomatic semantics

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

Hoare logic. Lecture 5: Introduction to separation logic. Jean Pichon-Pharabod University of Cambridge. CST Part II 2017/18

AXIOMS OF AN IMPERATIVE LANGUAGE PARTIAL CORRECTNESS WEAK AND STRONG CONDITIONS. THE AXIOM FOR nop

Semantics of programming languages

COSC252: Programming Languages: Semantic Specification. Jeremy Bolton, PhD Adjunct Professor

Lectures 20, 21: Axiomatic Semantics

Fundamentals and lambda calculus

Foundations. Yu Zhang. Acknowledgement: modified from Stanford CS242

Fundamentals and lambda calculus. Deian Stefan (adopted from my & Edward Yang s CSE242 slides)

Hoare Logic and Model Checking

(a) (4 pts) Prove that if a and b are rational, then ab is rational. Since a and b are rational they can be written as the ratio of integers a 1

Course notes for Data Compression - 2 Kolmogorov complexity Fall 2005

Introductory logic and sets for Computer scientists

Abstract Interpretation

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Chapter 3. Describing Syntax and Semantics

Introduction to Axiomatic Semantics (1/2)

The Typed λ Calculus and Type Inferencing in ML

Shared Variables and Interference

Program Syntax; Operational Semantics

Goals: Define the syntax of a simple imperative language Define a semantics using natural deduction 1

COMP 4161 NICTA Advanced Course. Advanced Topics in Software Verification. Toby Murray, June Andronick, Gerwin Klein

Topic 3: Propositions as types

Simply-Typed Lambda Calculus

Introduction to Axiomatic Semantics (1/2)

Hoare triples. Floyd-Hoare Logic, Separation Logic

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

CMSC 330: Organization of Programming Languages

Introduction to Lambda Calculus. Lecture 7 CS /08/09

Lambda Calculus. CS 550 Programming Languages Jeremy Johnson

6. Hoare Logic and Weakest Preconditions

Lecture Notes on Data Representation

PCP and Hardness of Approximation

Forward Assignment; Strongest Postconditions

PROPER TECHNIQUE OF SOFTWARE INSPECTION USING GUARDED COMMAND LANGUAGE

Chapter 3. Semantics. Topics. Introduction. Introduction. Introduction. Introduction

CS 161 Computer Security

CITS3211 FUNCTIONAL PROGRAMMING. 14. Graph reduction

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

λ calculus is inconsistent

Consider a description of arithmetic. It includes two equations that define the structural types of digit and operator:

Induction and Semantics in Dafny

LOGIC AND DISCRETE MATHEMATICS

Ambiguous Grammars and Compactification

Lambda Calculus and Type Inference

Programming Languages and Compilers Qualifying Examination. Answer 4 of 6 questions.

CS 242. Fundamentals. Reading: See last slide

The Diagonal Lemma: An Informal Exposition

Imperative Functional Programming

Software Paradigms (Lesson 4) Functional Programming Paradigm

COMP 507: Computer-Aided Program Design

Syntax-semantics interface and the non-trivial computation of meaning

Part II. Hoare Logic and Program Verification. Why specify programs? Specification and Verification. Code Verification. Why verify programs?

Reasoning About Imperative Programs. COS 441 Slides 10

The semantics of a programming language is concerned with the meaning of programs, that is, how programs behave when executed on computers.

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Warm-Up Problem. 1. What is the definition of a Hoare triple satisfying partial correctness? 2. Recall the rule for assignment: x (assignment)

Lambda Calculus and Type Inference

In Our Last Exciting Episode

Checks and Balances - Constraint Solving without Surprises in Object-Constraint Programming Languages: Full Formal Development

14.1 Encoding for different models of computation

Pure (Untyped) λ-calculus. Andrey Kruglyak, 2010

Shared Variables and Interference

CMSC 330: Organization of Programming Languages

(a) Give inductive definitions of the relations M N and M N of single-step and many-step β-reduction between λ-terms M and N. (You may assume the

Hoare Logic: Proving Programs Correct

3.7 Denotational Semantics

Recursively Enumerable Languages, Turing Machines, and Decidability

CSCC24 Functional Programming Scheme Part 2

Reminder of the last lecture. Aliasing Issues: Call by reference, Pointer programs. Introducing Aliasing Issues. Home Work from previous lecture

Reasoning about programs

Solution Set 8 Date: 1 December, 1992

Programming Languages

Last time. Reasoning about programs. Coming up. Project Final Presentations. This Thursday, Nov 30: 4 th in-class exercise

A CRASH COURSE IN SEMANTICS

Introduction to the Lambda Calculus

The Rule of Constancy(Derived Frame Rule)

Hoare Logic and Model Checking. A proof system for Separation logic. Introduction. Separation Logic

Joint Entity Resolution

Types, Expressions, and States

The Design of Core C++ (Notes)

Transcription:

Denotational Semantics of a Simple Imperative Language Using Intensional Logic Marc Bender bendermm@mcmaster.ca CAS 706 - Programming Languages Instructor: Dr. Jacques Carette Dept. of Computing and Software McMaster University 1

Introduction The standard approach to references in denotational semantics is to introduce addresses into the semantic domain. This method is inelegant when dealing with blocks and procedures with parameters passed by reference. Intensional logic is used for reasoning about senses (or intensions) of expressions. In imperative programming languages, it s very useful for dealing with the concept of references (as we will see). We will devise a system of intensional logic IL and use it to translate a simple Algol-like language, as in Janssen [1986] and Hung [1990]. 2

Sense and Denotation When we use an identifier that corresponds to some object, there is an inherent ambiguity as to what we mean: what the object denotes (its extension), or the object itself. For example, consider the identifier the temperature in the following expressions: the temperature is 20 the temperature is rising In the first occurence, we re making a statement about the current temperature. In the second, we mean the temperature itself (as a function of time). 3

To gain a better understanding of this situation, let s try to assign a type to the term in question. From the temperature is 20 we could infer that the temperature has type degrees. Say we now take a measurement of the temperature, and discover that it really is 20 i.e. the temperature = 20. We evaluate the predicate by substitution: 20 is 20 which is true, as we d expect. Now let s try to substitute into the temperature is rising : 20 is rising This clearly makes no sense. Somehow we ve introduced a type mismatch by substituting the same value for the same term. 4

Referential Transparency Vs. Referential Opacity We have the following important principle: Principle of Substitutivity of Equals: Substituting one term for another with the same meaning in an expression should not alter the meaning of that expression. In symbols: [[x] = [[y]] [[t]] = [[t [x/y]] Clearly this principle is very important in logic and mathematics. We call situations where the principle holds (e.g. the temperature is 20 ) referentially transparent; otherwise (e.g. the temperature is rising ) they are referentially opaque. Our goal is to restore the principle of substitutivity in opaque contexts. 5

Referential Opacity in Imperative Languages Suppose we have the program variables x and y which correspond to different memory locations, but both store the value 2. Compare the assignment statements z := y; z := x; Clearly they have the same result, that is to set z to 2. So the principle of substitutivity holds in this case; the RHS of an assignment statement is referentially transparent. Now consider these: y := 1; x := 1; Obviously they have different effects. So the LHS of an assignment statement is referentially opaque. We will solve this problem by translating statements into intensional logic. 6

Our System of Intensional Logic IL By state we will mean the internal memory configuration of the computer. We introduce three new operators for dealing with sense and denotation in imperative programming languages. Extension x gives us the value stored in location x in the current state. Intuitively this corresponds to dereferencing x. For example, if the value currently stored in x is 2, then x = 2. State switcher / x/n changes the state by overwriting the value in location x with n. This of course models assignment. Combining the two, we intuitively get x/n x = n 7

Intension Intension is almost the inverse of extension, i.e. t = t for any t, but t = t is not true in general. It can be interpreted (approximately) as a thunk or loaded reference. This is far more easily demonstrated than explained we start with a simple example. x = 2 means that x is roughly a virtual location that holds 2: x = 2 = 2. Intension becomes more interesting when it s applied to entire expressions: y = ( x + x) When we dereference y, we evaluate x in the present context. For example: x/1 y = x/1 ( x + x) = 1 + 1 = 2 8

The Formalized System IL IL is a higher order typed logic. The types τ,... are generated by τ ::= N B (τ 1 τ 2 ) (S τ) where N and B are the types of natural numbers and booleans, S is the type of states and τ 1 τ 2 is the type of functions. Notice that S is a hidden type there can be no terms of type S in IL. For each type τ we have a set of variables of type τ a set of constants of type τ, and the domain of τ, D τ. e.g. D B = {T, F}, D N = IN A valuation ρ is a function that assigns to each variable and constant of type τ a value in D τ. Constants are obviously always assigned the same values. 9

We define the special constants Loc g = {X, Y,... : (S N)} Array = {A,... : (N (S N))} Loc a = {A(n) A Array n IN} Loc = Loc g Loc a global locations arrays array elements The global locations and array elements are disjoint sets, that is they never share locations. Now define State to be the set of all states, i.e. functions σ : Loc IN. The meaning of an IL expression α : τ is then defined by structural recursion, relative to a state σ and valuation ρ: [[α]]σρ. We won t deal with the semantics here, for a full development see Hung [1990]. 10

IL has the usual arithmetic operations on N +,,,..., relations on N <, =,..., propositional connectives on B,,,..., quantifiers,, function application ( ), lambda abstraction plus our modal operators α : (S τ) for α : τ, α : τ for α : (S τ), and x/e α : τ for α : τ, x : (S N) and e : N. 11

Rigidity and β-conversion One of the key features of IL is its restricted form of β-conversion. First we define what it means for a term to be rigid. Definition (Rigidity): A term α is rigid if its value is the same in all states, i.e. [[α]σ 1 = [[α]]σ 2 for all σ 1, σ 2 State Theorem (β-conversion): For any IL term (λx α)(β), if either (1) β is rigid, or (2) no free occurrence of x in α lies within the scope of or /, then (λx α)(β) = α [x/β] where = denotes semantic equivalence. 12

Our Programming Language In order to demonstrate translation into IL, we ll use a simple Algol-like language. It consists of v: simple variables x, y,... and indexed variables a[e],..., e: arithmetical expressions and b: boolean expressions, S: program statements, generated by: S ::= skip v := e S 1 ; S 2 if b then S 1 else S 2 fi begin alias x = v; S end begin new x := e; S end 13

Backward Predicate Transformation Consider the Hoare triple {P } S {Q}. We consider assertions P, Q that extend the boolean expressions of our programming language by allowing quantifiers. Above, Q has type B. Consider q = Q, which has type (S B). q is a state predicate. Intuitively, it partitions State into two classes, that is, states that satisfy Q and states that don t. A program statement S is translated as a backward predicate transformer S : ((S B) B). For any assertion Q, S (q) is the weakest precondition that satisfies Q after the execution of S. 14

Translation into Intensional Logic We now translate the programming language into IL. The translation operator is. Variables We associate with each simple variable x an IL variable x : (S N) Similarly an array variable a is translated as a : (N (S N)). Expressions The translations of both arithetical expressions e and boolean expressions b are defined by structural induction on e and b; for example, (e 1 + e 2 ) = e 1 + e 2. An important point is that variables are dereferenced when viewed as a part of an expression, e.g. if e x then e = x 15

Translation of Statements In what follows, q is always assumed to be of type (S B). To illustrate the approach, we start by translating the trivial case: (skip) = λq q. If we apply this to some assertion Q, we get (skip) ( Q) = (λq q) Q = Q as we expect. Assignment isn t much more complicated: (x := e) = λq x /e q This justifies the intuitive connection of the state-switcher with the assignment statement. 16

Our translation of statement concatenation is (S 1 ; S 2 ) = λq S 1( (S 2(q)) ). Compare this with the backward predicate transformer S (q). The conditional is translated as follows: (if b then S 1 else S 2 fi) = λq (b S 1(q)) ( b S 2(q)). Now to the alias-block. Its function is to make x refer to the same location as v in S. This is where IL shines; the translation really couldn t be simpler: (begin alias x = v; S end) = (λx S )(v ) The magic behind this lies in our restrictive β-conversion rule. v can t be substituted into any intensional contexts unless it s rigid. 17

Memory Allocation and the new-block Translation of the new-block requires some sort of mechanism to provide new memory locations on demand. An IL array is well suited to the task. We will use two special IL variables j : (S N) and l : (N (S N)), where j is a counter used to index the allocator array l. l( j) provides us with the current empty location, and incrementing j allocates a new cell. By adhering to the policy of always incrementing j immediately after making use of l( j), we ensure that cells are never reallocated (to avoid unnecessary complication). We will use artificial program variables l and j for illustrative purposes they are completely invisible to the programmer. Naturally we set l = l and j = j. 18

The intuition behind the translation of the new-block is that we can model begin new x := e; S end as follows: begin alias x = l[j]; (j := j + 1; x := e; S) end We proceed by (1) getting the location of l[j] by aliasing x to it, (2) incrementing j (as per our policy), then (3) setting x to e. The translation is: (begin new x := e; S end) = (λx j/ j + 1 x /e S )(l( j) ) This last is my own contribution to the theory. The translation of the new-block in Hung [1990] is λq n [ l(n)/e (((λx S )(l(n)))( [n = j j/ j + 1 q])) ]. 19

Final Notes Many aspects of the theory were either skimmed or omitted altogether from this presentation, for time and complexity reasons. One interesting result that deserves mention is the state-switcher free precondition. By using a number of state-switcher reductions, Hung [1990] proves that the precondition can always be expressed in the assertion language alone, without using state switchers. Also interesting is the application of the theory to constructs involving double intensionality, such as pointers and pass-by-name parameters. 20

References J.W. de Bakker [1980], Mathematical Theory of Program Correctness, Prentice-Hall D.R. Dowty, R.E. Wall and S. Peters [1981], Introduction to Montague Semantics, D. Reidel H.K. Hung [1990], Compositional Semantics and Program Correctness for Procedures with Parameters, Ph.D Thesis, Computer Science Dept., SUNY-Buffalo, Technical Report 90-18 T.M.V. Janssen [1986], Foundations and Applications of Montague Grammar, Part 1: Philosophy, Framework, Computer Science, CWI Tract #19, Centre for Mathematics and Computer Science, Amsterdam J.I. Zucker and H.K. Hung [1991], Program Semantics, Intensional Logic and Compositionality, in Proceedings of the First Montreal Workshop on Programming Language Theory, April 1991. 21