Operational Semantics
description
Transcript of Operational Semantics
CSE 755, part2
Operational Semantics
Operational Semantics (O.S.):Specify Semantics by specifying how each command is to be executed.
One approach: Define an interpreter for the language.
Meta-circular interpreter:Interpreter in the same language
References:McCarthy and others: Lisp 1.5 programmer's manual
1
CSE 755, part2
Lisp Basics
Data types: Atomic & non-atomic s-expressions
Atomic s-exp: Numbers [we will use only integers] Strings [we won't use them] Symbols [i.e., identifiers]:
function names [built-in and user-defined] parameter names constants: T [for true], NIL [for false; also other key uses]
Non-atomic s-exp:If s1, s2 are s-exps, so is (s1 . s2)[so non-atomic s-exps are binary trees]
2
CSE 755, part2
Basic functions: cons[ s1, s2 ] = (s1 . s2) car[ (s1 . s2) ] = s1
Note: car[ s ] gives error if s is atomic cdr [ (s1 . s2) ]= s2
Note: cdr[ s ] gives error if s is atomic atom[ s ] = returns T/NIL if s is/isn't an atom null[ s ] = returns T/NIL if s is/isn't the atom NIL eq[ s1, s2]= ret. T/NIL if s1, s2 are/aren't the same atom
(null, eq may give errors if applied to non-atoms) plus[ s1, s2 ]: returns [s1 + s2] (must be numbers) minus[ s1, s2 ]: returns [s1 s2] (must be numbers) Etc.
Lisp Basics (contd.)
3
CSE 755, part2
Problem:Suppose we have four s-exps, s1, s2, s3, s4 that we want to keep together. Possible ways:
((s1 . s2) . (s3 . s4))
(s1 . (s2 . (s3 . s4)))
(((s1 . s2) . s3) . s4) [what about (s1 . s2 . s3 . s4) ?]
Standard solution:
(s1 . (s2 . (s3 . (s4 . NIL))))
Notation:
(s1 s2 s3 s4) denotes (s1 . (s2 . (s3 . (s4 . NIL))))
(s1 s2 s3) denotes (s1 . (s2 . (s3 . NIL)))
Important:
(s1 s2 s3) etc. is only a notation not a new type of s-exp
( ) denotes the atom NIL
4
CSE 755, part2
Lisp Basics (contd.)
car[ (2 3) ] = 2 cdr[(2 3) ] = ( 3 ) [Note: not 3 ] cons[ 2 , 3 ] = (2 . 3) [Note: not (2 3) ] cons[ 2 , ( 3 . NIL) ] = (2 . (3 . NIL))
same: cons[ 2 , ( 3 ) ] = (2 . (3 . NIL))same: cons[ 2 , ( 3 ) ] = (2 3)
cons[ (s1 s2), (s3 s4) ] = ((s1 s2) . (s3 s4))!= (s1 s2 s3 s4)
cons[ (s1 . s2), (s3 s4) ] = ((s1 . s2) . (s3 s4))= ((s1 . s2) s3 s4) [why?]
cons[ (s1 s2), (s3 . s4) ] ?cons[ (s1 . s2), (s3 . s4) ] ?
5
CSE 755, part2
Lisp Basics (contd.)
eq[ T, T] = T eq[ T, NIL] = NIL eq[ NIL, ()] = T eq[car[(2 . 3)], cdr[(3 . 2)]] = T eq[(2 . 3), (3 . 2)] : error; arguments to eq must be atoms eq[plus[2 , 3], minus[10, 5]]= T null[T] = NIL null[NIL]= T null[car[(2)]] = NIL null[cdr[(2)]] = T atom[car[(2)]] = T atom[cdr[(2)]] = T
6
CSE 755, part2
Lisp (the prog. lang.)
Lisp is not an imperative language Lisp is a functional programming language So:
No "internal state" that changes as program is "executed" In fact, no program variables whose values change over time! A program has no "side-effects"
Lisp runs in eval-print mode: Give the interpreter a Lisp Expression (not Lisp "program") It evaluates it, prints the value Waits for the next Lisp Expression
7
CSE 755, part2
Types of Lisp Expressions
1. Constants: 4, T, NIL, "xyz"
2. Function application:
(F a1 a2 a3 ... )
F is the function to be applied; a1, a2, ... the arguments
The interpreter first evaluates each argument, then applies F to the resulting values
Examples:
(plus 2 3) will output 5 // plus may be called "+"
(plus (plus 3 4) (plus 3 5)) will output 15
(car (3 . 4)) will output an error message!8
CSE 755, part2
Types of Lisp Exps. (contd.)
3. Quoted s-expressions:(quote s)
where s is any s-exp, not necessarily a Lisp expression;
The interpreter returns s as the value of (quote s)
Examples:(car (3 . 4)) will output error
(car (quote (3 . 4))) will output 3
(quote (3 . 4)) will output (3 . 4)
(cons (quote (1 . 2)) (quote (3 .4))) will output ((1 . 2) . (3 . 4))
(quote (cons (1 . 2) (3 . 4))) will output ??
(plus (car (2 . 3) ) (cdr (2 . 3)) ) will output ??
(plus (quote (2 . 3) ) (quote 3) ) will output ??
9
CSE 755, part2
3. Quoted s-expressions: (quote s) looks like a function call [with quote being the function called] but it is not; quote is a special form ]
4. Conditional:(cond (b1 e1) (b2 e2) ... (bn en) )
where each of b1, e1, b2, e2, ..., bn, en is a Lisp exp.
To evaluate: first evaluate b1; if it evaluates to T [i.e., non-NIL], evaluate e1 and return the resulting value;
if b1 evaluates to NIL, evaluate b2 and if it evaluates to non-NIL, evaluate e2 and return the resulting value;
if b1 and b2 both evaluate to NIL, evaluate b3 and ...
If b1, b2, ..., bn evaluate to NIL, error!
10
CSE 755, part2
Types of Lisp Exps. (contd.)
4. Examples
(cond (T NIL) (NIL T)) : evaluates to ??
(cond (NIL T) (T NIL)) : evaluates to ??
(cond (NIL T) (NIL NIL)) : evaluates to ??
(cond (T NIL) (T NIL)) : evaluates to ??
(cond
( (eq (plus 2 3) (minus 4 5)) 10 )
( (eq (plus 2 3) (times 4 5))20 )
( (eq (plus 2 3) (plus 4 5)) 30 )
( T NIL ) ) : evaluates to ??
cond is also a special form; why?
11
CSE 755, part2
Types of Lisp Exps. (contd.)
5. Function definition:
(defun f (p1 p2 ...) fb)f is the name of the function being defined;p1, p2, ... are the formal parameters of f;fb is the body of the function -- itself a Lisp exp.
The interpreter saves the definition of f for use when f is applied
Example:(defun sum (x y) (plus x y) )defines a function named sum that has two parameters whose names are x, y [types?], and whose body is as given
(sum 3 4) evaluates to 7
defun is also a special form; why?
That's it! That is (essentially) all of Lisp!12
CSE 755, part2
Examples
Examples:(defun equal (x y) ; x, y need not be atoms
(cond
( (atom x) (cond ( (atom y) (eq x y) )
( T NIL) )
( (atom y) NIL)
((equal (car x) (car y)) (equal (cdr x) (cdr y)) )
(T NIL) ) )
Consider: (equal 4 4) (equal 4 (plus 2 2))
(equal (car (2 . 3)) (plus 1 1) ) [watch out!]
13
CSE 755, part2
Examples:(defun equal (x y)
(cond( (atom x) (cond ( (atom y) (eq x y) ) ( T NIL) )
( (atom y) NIL)
( (equal (car x) (car y)) (equal (cdr x) (cdr y)) )
(T NIL) ) )
"Design" notation:
equal[x, y] = [ atom[x] [ atom[y] eq[x, y];
| T NIL; ]
| atom[y] NIL;
| equal[car[x], car[y]] equal[cdr[x], cdr[y]];
| T NIL; ]14
CSE 755, part2
Examples (contd.)
xmemb[x, list] : is x a member of list?
xmemb[x, list] =
[ null[list] NIL;
| eq[x, car[list]] T;
| T xmemb[x, cdr[list]]; ]
(defun xmemb (x list)
(cond
( (null list) NIL)
( (eq x (car list)) T)
( T (xmemb x (cdr list)) ) ) )
15
CSE 755, part2
Examples (contd.)
xunion[s1, s2] : s1, s2 are two lists; xunion must return s1 s2
xunion[s1, s2] =
[ null[s1] s2;
| null[s2] s1;
| T [ xmemb[car[s1], s2] xunion[cdr[s1],s2];
| T cons[car[s1], xunion[cdr[s1],s2] ]; ] ]
xunion[s1, s2] =
[ null[s1] s2;
| null[s2] s1;
| xmemb[car[s1], s2] xunion[cdr[s1],s2];
| T cons[car[s1], xunion[cdr[s1],s2] ]; ]
16
maxList[L] :: ; returns max of number in non-empty list L
; Functional:[ null[cdr[L]] car[L];| >[car[L], maxList[cdr[L]] car[L];| T maxList[cdr[L]] ]
; Functional but better:[ null[cdr[L]] car[L];| T bigger[ car[L], maxList[cdr[L]]] ] // define bigger
; "imperative":maxList[L] = max2[car[L], cdr[L]]max2[x, L] =
[ null[L] x;| >[x, car[L]] max2[x, cdr[L]];| T max2[ car[L], cdr[L] ] ]
Different styles in Lisp
CSE 755, part217
CSE 755, part2
Atoms: Constants: simple; others: look up on a-list
Function application: (F a1 a2 a3 ... an)F is a function that expects n parameters; each ai is a Lisp expression;Evaluate each ai; bind that value aiv to pi, the
corr. parameter, by adding (pi . aiv) to the a-list;
then evaluate the body of FNote: If F is not a built-in function, get def. from d-
list
How Lisp expressions are eval'd
18
CSE 755, part2
(QUOTE S) : simply return S
(COND (b1 s1) ... (bn sn) ) :Eval. b1; if result is non-NIL, eval. s1 and return its
value;else, eval. b2, if result is non-NIL, eval. s2 & return its
val;...; eval. bn, if non-NIL, eval. sn & return its val;if b1, ..., bn all eval to NIL, print error, escape to top;
(DEFUN F (p1 ... pn) fb) : add (F . ((p1 ... pn) . fb)) to d-list.
How Lisp expressions are eval'd
19
Can be written in Lisp fairly easily ... one reason: Lisp functions and Lisp exps. are s-exps.
eval: evaluates a Lisp-exp. given current parameter bindings (a-list) and fn. definitions (d-list)
apply: applies a function to given set of argument values - gets the fn. definition from d-list, binds the formal pars to corr. arg.vals, then calls eval to evaluate the body of the fn.
evcon: evaluates a conditional Lisp-exp: Given ((b1 e1) (b2 e2) ...): uses eval to evaluate b1, b2, ...until one, bi, evaluates to non-NIL; uses eval to evaluate corr.ei and returns its value.
evlis: evaluates a list of Lisp-exps.
Lisp Interpreter Details
CSE 755, part2 20
interpreter[dList] = eval[exp, NIL, dList] or better: output[ eval[input[], NIL, dList] ]
evlis[list, aList, dList] =[ null[list] NIL;| T cons[ eval[car[list], aList, dList], evlis[cdr[list], ..,..] ] ]
evcon[be, aList, dList] = // be is of form ((b1 e1) ... (bn en))[ null[be] NIL; // better: error!;| eval[caar[be], aList, dList] eval[cadar[be], aList, dList];| T evcon[cdr[be], aList, dList] ]
Lisp Interpreter Details (in Lisp)
CSE 755, part221
eval[ exp, aList, dList] =[ atom[exp] --> [ int[exp] --> exp
| eq[exp,T] --> T| eq[exp,NIL]--> NIL| in[exp,aList] --> getVal[exp,aList]| T --> "unbound variable!" ]
| atom[car[exp]] -->[ eq[car[exp],QUOTE] --> cadr[exp]| eq[car[exp],COND] --> evcon[cdr[exp], aList, dList]| eq[car[exp],DEFUN] --> "add to dList (state
change!)"| T --> apply[car[exp], evlis[cdr[exp],aList,dList],
aList, dList] ]| T --> "error!" ]
Lisp Interpreter Details (in Lisp)
CSE 755, part222
apply[ f, x, aList, dList] =[ atom[f] --> [ eq[f, CAR] --> caar[x]; // why?
| eq[f, CDR] --> cdar[x];| eq[f, CONS] --> cons[car[x], cdr[x]]; //??| eq[f, ATOM] --> atom[car[x]];| eq[f, NULL] --> null[car[x]];| eq[f, EQ] --> eq[car[x], cadr[x]]; | T --> eval[ cdr[getval[f, dList]],
addpairs[car[getval[f, dList]], x, aList],
dList ] ; ];| T --> "error!"; ]
Elements on dList of form: (f . (pList . body) )addpairs[pList,x,aList]: returns new a-list
Lisp Interpreter Details (in Lisp)
CSE 755, part2
23
We assumed s-expressions have been implemented; no way to specify how to do this within Lisp
Fact that Lisp-expns (to be evaluated) & function bodies were s-exps: key in writing a meta-circular interpreter (mci)
The mci for Lisp defines its operational sem. since it tells us how
Lisp-expns are to be evaluated -- but it assumes we have some basic knowledge about Lisp
You could change the o.s. of Lisp by rewriting appropriate parts of the main functions of the mci -- CLOS-MOP allows the Lisp programmer to do so!
Lisp Interpreter: Some comments
CSE 755, part2 24