Lecture 5: Declarative Programming. The Declarative Kernel Language Machine. September 12th, 2011

Similar documents
Lecture 6: The Declarative Kernel Language Machine. September 13th, 2011

Lecture 21: Relational Programming II. November 15th, 2011

Lecture 4: The Declarative Sequential Kernel Language. September 5th 2011

Programming Language Concepts, cs2104 Lecture 04 ( )

Lecture 8: Recursion and Iteration. Exceptions. Declarative Programming.

On Academic Dishonesty. Declarative Computation Model. Single assignment store. Single assignment store (2) Single assignment store (3)

COMP-421 Compiler Design. Presented by Dr Ioanna Dionysiou

Functional Programming. Pure Functional Programming

Don t write anything in the field marked Eventuell ekstra ID. For each subtask, choose the answer you think is the most correct one.

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

Introduction to Scheme

Operational Semantics. One-Slide Summary. Lecture Outline

Declarative Concurrency (CTM 4)

Declarative Computation Model

Programming Language Concepts, cs2104 Lecture 09 ( )

Compiler construction

Programming Language Concepts, cs2104 Lecture 01 ( )

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

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

Programming Languages Third Edition

2.2 Syntax Definition

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

6.001 Notes: Section 15.1

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

CSE 401 Compilers. LR Parsing Hal Perkins Autumn /10/ Hal Perkins & UW CSE D-1

To figure this out we need a more precise understanding of how ML works

Declarative concurrency. March 3, 2014

Functional programming with Common Lisp

CS143 Final Fall 2009

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

Declarative Programming Techniques

Formal Semantics. Chapter Twenty-Three Modern Programming Languages, 2nd ed. 1

Chapter 1. Fundamentals of Higher Order Programming

CSCI-GA Scripting Languages

Programming Language Concepts, CS2104 Lecture 7

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

Syntax-Directed Translation. Lecture 14

CMSC 330: Organization of Programming Languages. Operational Semantics

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Special Directions for this Test

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

Functional Programming in Haskell Part I : Basics

Parsing. Zhenjiang Hu. May 31, June 7, June 14, All Right Reserved. National Institute of Informatics

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

Introduction to Parsing. Lecture 5

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.

CS 242. Fundamentals. Reading: See last slide

CSE341: Programming Languages Lecture 6 Nested Patterns Exceptions Tail Recursion. Zach Tatlock Winter 2018

MIDTERM EXAM (Solutions)

SMURF Language Reference Manual Serial MUsic Represented as Functions

UNIT 3

Functional Programming. Pure Functional Programming

CSCC24 Functional Programming Scheme Part 2

Logic Programming (CTM ) Constraint Programming: Constraints and Computation Spaces

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

The Prolog to Mercury transition guide

This book is licensed under a Creative Commons Attribution 3.0 License

Problem with Scanning an Infix Expression

A Simple Syntax-Directed Translator

A Small Interpreted Language

News and remarks. CS68 Principles of Programming Languages. Contents today. Concurrency. Declarative concurrency. Threads

Sardar Vallabhbhai Patel Institute of Technology (SVIT), Vasad M.C.A. Department COSMOS LECTURE SERIES ( ) (ODD) Code Optimization

Lexical and Syntax Analysis. Top-Down Parsing

Review main idea syntax-directed evaluation and translation. Recall syntax-directed interpretation in recursive descent parsers

CSE 12 Abstract Syntax Trees

TAIL RECURSION, SCOPE, AND PROJECT 4 11

What s different about Factor?

15 212: Principles of Programming. Some Notes on Continuations

CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

LANGUAGE PROCESSORS. Introduction to Language processor:

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

CS 536 Introduction to Programming Languages and Compilers Charles N. Fischer Lecture 11

Syntax Errors; Static Semantics

Parsing Scheme (+ (* 2 3) 1) * 1

Coq Summer School, Session 2 : Basic programming with numbers and lists. Pierre Letouzey

Operational Semantics

Semantic Analysis. Lecture 9. February 7, 2018

Organization of Programming Languages CS3200/5200N. Lecture 11

CSE 341: Programming Languages

Working with recursion. From definition to template. Readings: HtDP, sections 11, 12, 13 (Intermezzo 2).

Working with recursion

Draw a diagram of an empty circular queue and describe it to the reader.

LECTURE 3. Compiler Phases

Functional programming in LISP

Midterm II CS164, Spring 2006

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Introduction to Parsing. Lecture 5

CSE P 501 Compilers. LR Parsing Hal Perkins Spring UW CSE P 501 Spring 2018 D-1

Syntactic Analysis. Top-Down Parsing

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

Exam for 2G1512 DatalogiII, Apr 12th

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

Lecture 2: SML Basics

An Oz Subset. 1 Microsyntax for An Oz Subset. Notational Conventions. COP 4020 Programming Languages 1 January 17, 2012

Intermediate representations IR #1: CPS/L 3. Code example. Advanced Compiler Construction Michel Schinz

CS 4240: Compilers and Interpreters Project Phase 1: Scanner and Parser Due Date: October 4 th 2015 (11:59 pm) (via T-square)

Declarative Concurrency (CTM 4)

6.001 Notes: Section 6.1

Programming Languages Third Edition. Chapter 7 Basic Semantics

Project 2: Scheme Interpreter

Transcription:

Lecture 5: Declarative Programming. The Declarative Kernel Language Machine September 12th, 2011 1

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 2

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 3

Dataflow Variables contd Unbound variables and freezing If an unbound variable is used in an operation that needs the value of the variable, the computation freezes. In the sequential model of computation it means that the whole execution of the program halts, as there is no way to provide the value. In a concurrent environment, it is just one thread that is kept waiting, while other threads may provide the needed value. 4

Dataflow Variables contd Example (Freezing) declare X Y in Y = X + 2 % (1) {Browse Y} % (2) (1) The computation freezes here neither X nor Y are bound. The interpreter waits for X to become bound because its value is needed to compute the arithmetic operation. There is no other thread which could do the binding, so we stop. (2) The {Browse Y} statement is never reached there will be no output. Try it! 5

Dataflow Variables contd Browse again Browse introduces a new separate thread in which the browser displays a value. Browse does not belong to the declarative sequential model of computation. 6

Dataflow Variables contd Example (Browse and freezing) declare X in {Browse X} % (1) X = 1 % (2) (1) No freezing Browse starts a new thread in which it displays an unbound variable, the thread is stopped, and the main thread proceeds. (2) X becomes bound to 1, the Browse thread is reactivated, and the output is updated. We can visualize what happens if we introduce a delay between (1) and (2) (e.g., with the statement {Delay 2000}). 1 Try it! 1 Delay does not belong in the model of computation, but will often be useful for visualization. 7

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 8

Expressions and Statements Expressions An expression is a syntactic construct which specifies an operation that evaluates to a value. Example (Expressions) 2 + 2 evaluates to 4. A==B evaluates to true or false. proc {$ X} X=1 end evaluates to a procedure. {fun {$ X} X+1 end 1} evaluates to the result of an application of an anonymous function to the value 1, which is 2. 9

Expressions and Statements contd Statements An statement is a syntactic construct which specifies an operation that does not evaluate to a value. Example (Statements) X=1 unifies X with 1. {Browse X+1} displays the value of X+1. skip causes the execution to proceed without any action, a no-operation statement. {proc {$} {Browse done} end} applies a procedure of no arguments. 10

Expressions and Statements contd Expressions or statements? A program in the declarative sequential kernel language is composed exclusively of statements. But in the extended/practical language, X=1 can be used both as a statement and as an expression: X = 1 % valid Y = X = 1 % likewise In CTMCP, such syntactic structures are called nestable constructs (App. C.2). 11

Expressions and Statements contd If-then-else constructs can be used as both statements and expressions, depending on the nested instructions. Example (if-statements and if-expressions) These two pieces of code are equivalent: local X in if A > B then X = A else X = B end {Browse X} end {Browse X = if A > B then A else B end} Try it! 12

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 13

Functions and Procedures Functions are linguistic abstractions over procedures. Any function definition and application can be translated into a corresponding procedure definition and application. A function of n arguments is a procedure of n + 1 arguments a function s return value is bound to an additional, implicit argument. A procedure may have more than one result arguments. A function can also have more than one result argument, but only one of them is implicit. For convenience, result arguments may be marked with the prefix?. 2 Since functions are a linguistic abstraction over procedures, it should be possible to use them interchangeably. 2 This is just a syntactic convenience for the programmer, and is entirely ignored by the compiler. 14

Functions and Procedures contd Example (An application of a procedure as an expression) Procedure = proc {$?X} X = 1 end {Browse {Procedure}} Example (An application of a function as a statement) Function = fun {$} 1 end local Result in {Function Result} {Browse Result} end Cool, but we ll try to avoid such misuse of the constructs. 15

Functions and Procedures contd Example (Factorial, a recursive function) Consider a simple recursive function that computes n! (the factorial of n): declare Factorial = fun {$ N} if N < 2 then 1 else N * {Factorial N - 1} end end {Browse {Factorial 10}} This is a program in the practical language. 16

Functions and Procedures contd Example (Factorial, a recursive function contd) We can rewrite the program in the (quasi) kernel language as follows: declare Factorial Result in Factorial = proc {$ N?Result} local Test in Test = N < 1 if Test then Result = 1 else local NestedResult NMinusOne in NMinusOne = N - 1 {Factorial NMinusOne NestedResult} Result = N * NestedResult end end end end {Factorial 10 Result} {Browse Result} 17

Functions and Procedures contd And now some magic... 18

Functions and Procedures contd Example (Magic) What does the function do? fun {Magic X Y} record(x Y) end 19

Functions and Procedures contd Example (Magic) What does the function do? fun {Magic X Y} record(x Y) end declare X in X = {Magic 1 2} 19

Functions and Procedures contd Example (Magic) What does the function do? fun {Magic X Y} record(x Y) end declare X in X = {Magic 1 2} declare X Y in record(1 2) = {Magic X Y} 19

Functions and Procedures contd Example (Magic) What does the function do? fun {Magic X Y} record(x Y) end declare X in X = {Magic 1 2} declare X Y in record(1 2) = {Magic X Y} Magic unifies its implicit result argument with a record containing X and Y as (partial) values. The binding can go both ways. Try it! 19

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 20

Data Structures In Oz, the most important data structure is record. A record has a label and any number of named feature-field pairs (or key-value pairs, with feature=key, field=value). A record without any field is an atom: atom == atom() % true {Record.label atom} == atom() % true (!) Syntactically, the forms label and label () are not equivalent: X = record(feature:value) % valid X = record()(feature:value) % invalid A record without explicit features is a tuple: tuple(a b c) == tuple(1:a 2:b 3:c) % true 21

Records contd Records are useful for constructing nested (recursive) data structures. Example (Representing trees with records) This tree: tree tree tree leaf leaf tree leaf leaf can be represented with nested records as: leaf Tree = tree(left:tree(left:leaf right:leaf) right:tree(left:tree(left:leaf right:leaf) right:leaf)) 22

Records contd In the example above, a leaf node is a 0-field record (an atom) with the label leaf; an intermediate node is a 2-field record with the label tree, the features left and right, and two trees as values. We can use pattern matching to perform operations on trees. Example (Counting leaf nodes in a tree) fun {CountLeaves Tree} case Tree of leaf then 1 [] tree(left:left right:right) then {CountLeaves Left} + {CountLeaves Right} end end For now we use handwaving semantics to explain pattern matching, but will come to a more precise explanation soon. 23

Records contd The height of a tree is the count of nodes on the longest path from the root to a leaf. Example (Computing the height of a tree) fun {Height Tree} case Tree of leaf then... [] tree(left:left right:right) then... end end 24

Records contd The height of a tree is the count of nodes on the longest path from the root to a leaf. Example (Computing the height of a tree) fun {Height Tree} case Tree of leaf then 1 [] tree(left:left right:right) then {Max {Height Left} {Height Right}} + 1 end end 24

Records contd The tupling constructor # is a convenient syntactic sugar for building records. X#Y#Z is a record with the label #, and three features named 1, 2, and 3, with the fields of X, Y, and Z, respectively: X#Y#Z == # (1:X 2:Y 3:Z) % true When the features are consequtive integers, it is convenient to avoid typing them: X#Y#Z == # (X Y Z) % true The tupling constructor is typically used when we want to pattern-match more than one variable. 3 3 Typically in the book. There are other ways to achieve this effect. 25

Records contd Example (Pattern matching with #) Instead of case X of record(feature:xvalue) then case Y of record(feature:yvalue) then % use XValue and YValue else skip end else skip end we can write case X#Y of record(feature:xvalue)#record(feature:yvalue) then % use XValue and YValue else skip end 26

Lists What is a list? In abstract terms, a list is an ordered collection of items. In Oz, lists are chains of nested records (they are single-linked lists). Example (Lists) [one two three] % a three-element list [one [two three]] % a two-element nested list nil % the empty list [] % not a list! Note: [] is used in pattern matching in the extended/practical language to separate alternative patterns. 27

Lists contd A list is a nested sequence of records. The records that form a list have the label and exactly two fields with the features 1 and 2. The feature 1 of the first (topmost) record names the field which keeps the first element of the list (the head of the list). The feature 2 of the first record names a field which keeps the rest of the list (the tail of the list). The rest of the list is another list either another record with analogous structure, or the empty list. 28

Lists contd Example (Lists) (one nil) (1:one 2:nil) (2:nil 1:one) (nil one) (nil nil) (one (two nil)) ( (one nil) nil) Note: (nil one) is the same as (1:nil 2:one) and not (1:one 2:nil); since one is not a list, (nil one) is not a list either. 29

Lists contd Example (Lists) (one nil) % a list (1:one 2:nil) % a list (2:nil 1:one) % a list (nil one) % not a list (the tail is not a list) (nil nil) % a list (the head is the empty list) (one (two nil)) % a 2-element list ( (one nil) nil) % a 1-element list Note: (nil one) is the same as (1:nil 2:one) and not (1:one 2:nil); since one is not a list, (nil one) is not a list either. 29

Lists contd For most of the time, we will use syntactic sugar while talking about lists. Example (Lists) [one two] one two nil one two % equivalent to (one (two nil)) % equivalent to (one (two nil)) % not a list -- equivalent to (one two) Note: Both # and are used to construct records, but they are treated differently: 1#2#3 % flat record: # (1 2 3) 1 2 3 % nested record: (1 (2 3)) 1#2#nil % flat record: # (1 2 nil) 1 2 nil % nested record: (1 (2 nil)) -- a list [1 2] 30

Lists contd Example (Building a list) We can build a list piecewise from the end towards the start: local A B C in C = nil B = two C A = one B {Browse A == [one two]} % true end We can also build a list piecewise from the start towards the end: local A B C in A = one B B = two C C = nil {Browse A == [one two]} % true end 31

Lists contd A list can be seen as a tree where intermediate nodes are records with the label. Example (Lists are trees) [1 2 3] == (1 (2 (3 nil))) 1 2 3 nil 32

Lists contd The arity of a record is a collection of all its features sorted alphanumerically. In Oz, the arity of a record is a list of its features, sorted. Example (The arity of a record as a sorted list) {Record.arity record(one two three)} % [1 2 3] {Record.arity record(1:one 3:two 2:three)} % [1 2 3] {Record.arity record(one two:two three)} % [1 2 two] {Record.arity record(4:b 12:c a 4 :d 12 :e)}% [1 4 12 12 4 ] 33

Lists contd We can use pattern matching to access elements of a list. Example (Appending lists) fun {Append List1 List2} case List1 of nil then... [] Head Tail then... end end {Append [1 2] [3 4]} % evaluates to [1 2 3 4] {Append nil [3 4]} %? {Append [1 2] nil} %? 34

Lists contd We can use pattern matching to access elements of a list. Example (Appending lists) fun {Append List1 List2} case List1 of nil then List2 [] Head Tail then Head {Append Tail List2} end end {Append [1 2] [3 4]} % evaluates to [1 2 3 4] {Append nil [3 4]} % evaluates to [3 4] {Append [1 2] nil} % evaluates to [1 2] 34

Lists contd We can further improve our implementation of append by pattern-matching over both lists. Example (Appending lists contd) fun {Append List1 List2} case List1#List2 of nil#_ then List2 [] _#nil then List1 [] (Head Tail)#_ then Head {Append Tail List2} end end Compare to how this could be done in, e.g., Erlang: append([],list) -> List; append(list,[]) -> List; append([head Tail],List) -> [Head append(tail,list)]. 35

Lists contd Example (Merging lists) Using recursion and pattern matching we can merge sorted lists into one sorted list. fun {MergeSorted List1 List2} case List1#List2 of nil#_ then... [] _#nil then... [] (Head1 Tail1)#(Head2 Tail2) then... end end 36

Lists contd Example (Merging lists) Using recursion and pattern matching we can merge sorted lists into one sorted list. fun {MergeSorted List1 List2} case List1#List2 of nil#_ then List2 [] _#nil then List1 [] (Head1 Tail1)#(Head2 Tail2) then if Head1 < Head2 then Head1 {MergeSorted Tail1 List2} else Head2 {MergeSorted List1 Tail2} end end end 36

Lists contd Mapping is a higher-order programming technique where we apply a function to all elements of a list. Map is a function that takes two arguments: a list and a one-argument function, and returns a list of the results of application of the function to every element of the input list. Example (Mapping) {Map [1 2 3] fun {$ Item} Item + 1 end} % evaluates to [2 3 4] {Map [1#2 2#3 3#4] fun {$ Item} case Item of X#Y then if {IsOdd X} then Y else X end end end} % evaluates to [2 2 4] 37

Lists contd Example (Mapping) We can do more tricky things with Map: {Map [fun {$ X} X + 1 end fun {$ X} X * 2 end...] fun {$ Function} {Function 2} end} % evaluates to [3 4...] Here we apply to a list of one-argument functions a function that takes a one-argument function as an argument and applies that function to the number 2. This is a typical example of functional higher-order programming (HOP). Other HOP techniques include filtering, folding, accumulating, etc. More on this later. 38

Magic? Any sufficiently advanced technology is indistinguishable from magic. Arthur C. Clarke Any technology distinguishable from magic is insufficiently advanced. (author unknown) 39

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 40

Entering the Core of Oz... 41

The Abstract Machine So far we have discussed (some of) the theoretical aspects of syntactic specifications of programming languages, and used elements of this theory to specify the syntax of the declarative sequential kernel language (DSKL). We have also explained, in an intuitive, informal way, how constructs of DSKL work when they are executed. We will now develop a more precise specification of the meaning of DSKL programs by means of the DSKL Abstract Machine (or Virtual Machine, VM), and use Oz to partially implement the VM. The VM is a model of computation 4 explaining the execution of programs while hiding details of the underlying physical machine (processors, registers, memory, etc.) below a layer of abstraction. 4 Or is Oz itself a model of computation? 42

The Abstract Machine contd Components of the abstract machine The VM has two principal components: 1. A semantic stack. 2. A single assignment store. Abstract machine Semantic stack Semantic statement Semantic statement Semantic statement... Single assignment store 43

The Abstract Machine contd To visualize computations on the VM, we will use the following notation: The VM is a pair M of the semantic stack S and the single assignment store σ: M = (S, σ) To show how a computation proceeds, we will illustrate it as a sequence of consequtive states of the VM: Step 1: M(t 1 ) = (S 1, σ 1 ) Step 2: M(t 2 ) = (S 2, σ 2 )...... 44

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 45

The Semantic Stack The semantic stack The semantic stack contains semantic statements. A semantic statement is a pair composed of a (parsed) statement and an environment. The statement is a piece of program to be evaluated. The environment is a mapping from identifiers in the code to variables in the store. We will use the following notation: The semantic stack S is a list of semantic statements: S = [s 1, s 2,...] A semantic statement s is a pair of a statement and an environment: s i = ( statement i, E i ) 46

The Semantic Stack contd Note: In CTMCP, the statements on the semantic stack are shown as pieces of source code. In practice, this would require parsing during execution, and the same piece of code might need to be parse more than once (e.g., when recursion is used). We will follow the book s notation in the theoretical part, but will use parsed statements in our implementation. 5 5 Our VM will take as input parse trees rather than source code; we will not develop a parser for DSKL at the moment. 47

The Semantic Stack contd Environments An environment is a mapping between identifiers in statements and variables in the single assignment store. We will use the following notation: An environment E is a set of identifier-variable pairs: E = { id 1 v 1, id 2 v 2,...} 48

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 49

The Single Assignment Store Single assignment store The single assignment store contains declarative variables (dataflow variables, variables). A number of operations on the variables in the store are allowed: Creation of a new, unbound variable. Binding of an unbound variable to another unbound variable. Binding of an unbound variable to a bound variable (to a value). Unification of two bound variables (of two values). Testing whether a variable is bound or not. 6 Retrieving the value of a bound variable. Testing equivalence between two variables. We will use the following notation: The single assignment store σ is a set of variables, bound or not: σ = {v 1, v 2 = 1, v 3 = rec(feat : v 1 ), v 5 = v 6...} 6 Testing whether a variable is bound (IsDet) is not allowed in the declarative model. 50

The Single Assignment Store contd Note: A variable bound to a value will have that value until the end of the computation. 7 A variable bound to another variable will always have the same value as that other variable. 8 Note: Variable names are not variables: names are elements of the code, variables are elements of the abstract machine. The same identifier may map onto different variables within one program, a variable cannot have different values during an execution. 7 Or until it is garbage-collected more on this later. 8 Or both remain unbound. 51

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 52

Operations on Variables Creation of a variable... % (1) declare X in % (2)... (1) Single assignment store (2) Single assignment store v 1 unbound 53

Operations on Variables contd Unification of unbound variables (variable-variable binding) declare X Y in % (1) X = Y % (2) (1) Single assignment store (2) Single assignment store v 1 unbound v 1 unbound v 2 unbound v 2 unbound 54

Operations on Variables contd Binding of a variable to a value declare X in % (1) X = tree(leaf leaf) % (2) (1) Single assignment store (2) Single assignment store v 1 unbound v 1 bound tree leaf leaf 55

Operations on Variables contd Binding of one of equivalent variable to a value declare X Y in X = Y % (1) X = atom % (2) (1) Single assignment store (2) Single assignment store v 1 unbound v 1 bound atom v 2 unbound v 2 bound 56

Operations on Variables contd Binding of a variable to a partial value declare X Y in % (1) X = record(y) % (2) (1) Single assignment store (2) Single assignment store v 1 unbound v 1 bound record v 2 unbound v 2 unbound 57

Operations on Variables contd Unification If two complete values are of the same type and have the same structure and content, unification succeeds; no additional binding is performed. Example (Unification) declare X Y in X = tree(leaf leaf) Y = tree(leaf leaf) X = Y % (1) (1) Unification succeeds, no new bindings are made. 58

Operations on Variables contd Unification contd If a partial value is unified with another (possibly partial) value, unification succeeds if the existing content can be unified; additional binding is performed as needed. Example (Unification contd) declare X Y in X = tree(_ leaf) % X has a nested, anonymous unbound variable Y = tree(leaf _) % Y has a nested, anonymous unbound variable X = Y % (1) (1) Both X and Y are records, their labels are identical, and recursive unification of their content causes two new bindings to be made. 59

Operations on Variables contd Unification contd If two (partial or complete) values do not match at some place of their structure, unification fails; 9 Additional binding may be performed. 10 Example (Unification contd) declare X Y in X = tree(leaf leaf) Y = tree(leaf bird) X = Y % (1) (1) Both X and Y are records, their labels are identical, their features are identical, but not all of their fields have compatible values unification fails. 9 An error is raised, which we can catch as an exception more on this later. 10 Whether additional bindings will or will not be made depends on the order in which nested unifications are done, and is an implementational detail. See next slide. 60

Operations on Variables contd In some cases, unification failures are discovered at the compile time. Example (Compile-time unification failure) declare X Y in {Browse Y} % (2) X = tree(leaf leaf) X = tree(bird Y) % (1) (1) This statement causes a compile-time failure. (2) The program is actually not executed, and this statement produces no output. 61

Operations on Variables contd In some cases, unification failures are discovered at the run time. Example (Run-time unification failure) declare X Y P in X = tree(leaf leaf) proc {P X Y} X = tree(worm Y) % note the order of values end {Browse Y} % (1) {P X Y} % (2) There is no unification failure here that would be discovered at compile time. (1) This statement causes Y to be displayed (as an unbound variable). (2) This statement causes a run-time unification failure; Y remains unbound and the output does not change. 62

Operations on Variables contd In some cases, unification failures are discovered at the run time. Example (Run-time unification failure contd) declare X Y P in X = tree(leaf leaf) proc {P X Y} X = tree(y worm) % note the order of values end {Browse Y} % (1) {P X Y} % (2) There is no unification failure here that would be discovered at compile time. (1) This statement causes Y to be displayed (as an unbound variable). (2) This statement causes a run-time unification failure, but when it occurs Y has already been bound to leaf and the output updated. 63

Operations on Variables contd Testing equality between variables If it can be established that two variables will always have the same value, the test evaluates to true. Example (Testing equality between variables) declare X Y in X = Y {Browse X == Y} % (1) (1) Because X and Y are equivalent (bound together in the store), binding one of the to a value automatically binds the other to the same value. Therefore, true is displayed. 64

Operations on Variables contd Testing equality between variables contd If it can be established that two variables will always have the same value, the test evaluates to true. Example (Testing equality between variables contd) declare X Y in X = tree(leaf leaf) Y = tree(leaf leaf) {Browse X == Y} % (1) (1) Because X and Y are already bound and have unifiable complete values, they will always have the same value. Therefore, true is displayed. 65

Operations on Variables contd Testing equality between variables contd If it can be established that two variables will never have the same value, false is returned. Example (Testing equality between variables contd) declare X Y in X = tree(leaf leaf) Y = leaf {Browse X == Y} % (1) (1) Because X and Y are already bound and their values are not unifiable, they will never have the same value. Therefore, false is displayed. 66

Operations on Variables contd Testing equality between variables contd If it cannot be established that two variables will always have the same value, and it cannot be established that they will never have the same value, the computation suspends. 11 Example (Testing equality between variables contd) declare X Y in X = tree(leaf leaf) Y = tree(leaf _) {Browse X == Y} % (1) (1) Because Y is bound to a partial value and it is not know what value will the second field of Y have, equality cannot be established and nothing is displayed. 11 In a concurrent environment, the thread performing the test stops. 67

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 68

Operations on Environments Operations on environments Adjunction adds mappings creating a new, extended environment. E = E + { id v 1,...} where id stands for an identifier, and v i for a variable. If E already contains a mapping for id, this mapping is replaced in E with the new one. Note: In this model, environments are immutable; E does not change operations on environments are functional. Example (Adjunction) E = {A v 1 } E = E + {B v 2 } = {A v 1,B v 2 } E = {A v 1 } E = E + {A v 2 } = {A v 2 } 69

Operations on Environments contd Operations on environments contd Restriction removes mappings creating a new, reduced environment: where id stands for an identifier. E = E { id,...} E contains only those mappings from E which involve identifiers from the specified set. If E does not contain a mapping for some of those identifiers, E does not contain such a mapping either. Example (Restriction) E = {A v 1,B v 2 } E = E {A,C} = {A v 1 } E = {A v 1,B v 2 } E = E {} = {} 70

Operations on Environments contd Operations on environments contd Lookup retrieves variables corresponding to specified identifiers based on the mappings in an environment: v = E( id ) where id stands for an identifier, and v stands for a variable. E( id ) returns the variable onto which id is mapped in E. It is an error if E does not contain a mapping for id. Example (Lookup) E = {A v 1,B v 2 } E(A) = v 1 E = {A v 1,B v 2 } E(C) causes a lookup error. 71

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 72

Computations Computations A computation is a stepwise execution of a program. One step involves the following operations on the abstract machine: 1. Pop the topmost semantic statement from the semantic stack. 2. Execute the enclosed statement using mappings in the enclosed environment and bindings in the single assignment store. 3. Modify the semantic stack and the store as needed. 4. If the semantic stack is not empty, repeat. An empty stack means no further computation can be made the execution has finished. The stack does not have to shrink each execution step may result in pushing one or more semantic statements onto the stack. 73

Computations contd How does a computation proceed? Let statement 0 be a program. 12 The abstract machine is initialized as follows: 1. Create an empty environment: 2. Create a semantic statement: E 0 = {} s 0 = ( statement 0, E 0 ) 3. Create a semantic stack and push onto it the initial semantic statement: S 0 = [s 0 ] 4. Create an empty single assignment store: σ 0 = {} 5. Create the initial state of the abstract machine: M 0 = ( S 0, σ 0 ) 12 A program is a statement, possibly a sequence of statements recall the grammar for DSKL. 74

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 75

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 2. Otherwise, 2.1 take the first semantic statement, s i 1 = ( statement i 1, E i 1 ), from the stack; 75

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 2. Otherwise, 2.1 take the first semantic statement, s i 1 = ( statement i 1, E i 1 ), from the stack; 2.2 execute statement i 1 using, if necessary, mappings from E i 1 and bindings from σ i ; 75

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 2. Otherwise, 2.1 take the first semantic statement, s i 1 = ( statement i 1, E i 1 ), from the stack; 2.2 execute statement i 1 using, if necessary, mappings from E i 1 and bindings from σ i ; 2.3 update the state of the semantic stack from S i to S i+1 by removing the topmost semantic statement (the one just executed) and pushing onto it new semantic statements if needed; 75

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 2. Otherwise, 2.1 take the first semantic statement, s i 1 = ( statement i 1, E i 1 ), from the stack; 2.2 execute statement i 1 using, if necessary, mappings from E i 1 and bindings from σ i ; 2.3 update the state of the semantic stack from S i to S i+1 by removing the topmost semantic statement (the one just executed) and pushing onto it new semantic statements if needed; 2.4 update the state of the single assignment store from σ i to σ i+1 by adding new variables and performing bindings, if needed; 75

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 2. Otherwise, 2.1 take the first semantic statement, s i 1 = ( statement i 1, E i 1 ), from the stack; 2.2 execute statement i 1 using, if necessary, mappings from E i 1 and bindings from σ i ; 2.3 update the state of the semantic stack from S i to S i+1 by removing the topmost semantic statement (the one just executed) and pushing onto it new semantic statements if needed; 2.4 update the state of the single assignment store from σ i to σ i+1 by adding new variables and performing bindings, if needed; 2.5 in case of problems, stop and report failure. 75

Computations contd How does a computation proceed? contd Start the machine in the initial execution state M 0 as described above. Use the following algorithm: 1. If in the current execution state, M i = ( S i, σ i ), the semantic stack S i is empty, stop and report success. 2. Otherwise, 2.1 take the first semantic statement, s i 1 = ( statement i 1, E i 1 ), from the stack; 2.2 execute statement i 1 using, if necessary, mappings from E i 1 and bindings from σ i ; 2.3 update the state of the semantic stack from S i to S i+1 by removing the topmost semantic statement (the one just executed) and pushing onto it new semantic statements if needed; 2.4 update the state of the single assignment store from σ i to σ i+1 by adding new variables and performing bindings, if needed; 2.5 in case of problems, stop and report failure. 3. Update the state of the machine from M i to M i+1 = ( S i+1, σ i+1 ), and go to 1. 75

Lecture Outline Declarative Programming contd Dataflow Variables contd Expressions and Statements Functions and Procedures Data structures The Abstract Kernel Language Machine The Semantic Stack The Single Assignment Store Operations on Variables Operations on Environments Computations Summary 76

Summary This time Next time Homework Pensum Questions? Dataflow variables, expressions, statements, procedures and functions, data structures. Operational Semantics of the Declarative Sequential Kernel Language the abstract machine. Step-by-step execution of statements on the abstract machine. Implementation of a virtual machine for a subset of DSKL. Read Ch. 2 in CTMCP (focus on the semantic of the kernel language). Solve Exercise 1. All of today s slides. 77