1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global.

Slides:



Advertisements
Similar presentations
1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Advertisements

1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
Scheme in Scheme?!? …the metacircular evaluator….
1 The metacircular evaluator Names Extend the calculator to store intermediate results as named values (define x (+ 4 5)) store result as x (+ x.
Imperative Programming: Mutable data (local state, letrec, set!) Example 1: counter (define counter (let ((count 0)) (lambda () (set! count (+ count 1))
1 Programming Languages (CS 550) Operational Semantics of Scheme using Substitution and the Lambda Calculus Jeremy R. Johnson TexPoint fonts used in EMF.
1-1 An Introduction to Scheme March Introduction A mid-1970s dialect of LISP, designed to be a cleaner, more modern, and simpler version than.
Metacircular Evaluation SICP Chapter 4 Mark Boady.
Evaluators for Functional Programming Chapter 4 1 Chapter 4 - Evaluators for Functional Programming.
Imperative Programming: Mutable data (local state, letrec, set!) Example 1: counter (define counter (let ((count 0)) (lambda () (set! count (+ count 1))
Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:
1 Programming Languages (CS 550) Lecture 7 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts used in EMF. Read.
מבוא מורחב למדעי המחשב תרגול 13 Lazy Evaluation. Lazy Evaluation Implementation Two types of values – Delayed Values – Actual Values Introduce two functions.
1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Metacircular Evaluator 4.1, pages definitions file on web 2.
(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((list-form? exp) (eval-list.
1 Lecture 18 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 21. Overview 1. Dynamic Binding 2. Lazy Evaluation 3. More MC-Eval 2.
6.001 SICP SICP – Evaluation I Recitation 11/19/2004 Eval review Evaluation examples define lambda apply New language elements.
SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Techniques for language design: Interpretation: eval/apply Semantics vs. syntax Syntactic.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Scheme More MCE examples. Q1 new special form which defines global variables (static ) search the global environment – Variable exists: does nothing,
PPL Syntax & Formal Semantics Lecture Notes: Chapter 2.
PPL Syntax & Formal Semantics Lecture Notes: Chapter 2.
The environment model evaluator and compiler 1 The env model evaluator Motivation In one word: Efficiency Saves repeated renaming and substitution: Using.
1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.
PPL Pairs, lists and data abstraction. Data Abstraction? An interface: separate implementation from usage Think of the Map interface in Java: we know.
PPL Pairs, lists and data abstraction. Compound Data Until now: atomic, unrelated entities Now: organized into structures Why? – Better conceptual level.
1 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure + symbol.
1 Programming Languages (CS 550) Lecture 5 Summary Object Oriented Programming and Implementation* Jeremy R. Johnson *Lecture based on notes from SICP.
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is aa good way to learn more about programming languages  Interpreters are.
1 The metacircular evaluator (Cont.) Defining new procedures (define (lambda? e) (tag-check e 'lambda)) (define (eval exp env) (cond ((number? exp)
CS220 Programming Principles 프로그래밍의 이해 2002 가을학기 Class 15: Meta-Circular Evaluator 한 태숙.
SICP Interpretation Parts of an interpreter Arithmetic calculator Names Conditionals and if Storing procedures in the environment Environment as.
The environment-based operational semantics Chapter
1 Read-Eval-Print Loop (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (eval input the-global-env))) (announce-output.
1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)
Example 1: counter (set! vs set-box!) 1 Imperative Programming: Mutable data and local state (define counter (let ((count 0)) (lambda () (set! count (+
Example 1: counter (set! vs set-box!) 1 Imperative Programming: Mutable data and local state (define counter (let ((count 0)) (lambda () (set! count (+
Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
1 Lecture 19 Dynamic Scoping Lazy Evaluation (4.2.1, 4.2.2)
1/ SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Making the environment model concrete Defining eval defines the language –Provides.
CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
Evaluators for Functional Programming 1. How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
Operational Semantics of Scheme
6.001 SICP Object Oriented Programming
The interpreter.
Introduction to Scheme
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Env. Model Implementation
Original material by Eric Grimson
The Metacircular Evaluator
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
The Metacircular Evaluator (Continued)
Lecture 26: The Metacircular Evaluator Eval Apply
Streams, Delayed Evaluation and a Normal Order Interpreter
Lecture #9 מבוא מורחב.
Lecture 12: Message passing The Environment Model
6.001 SICP Variations on a Scheme
6.001 SICP Interpretation Parts of an interpreter
topics interpreters meta-linguistic abstraction eval and apply
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global Environment. Op. semantics (evaluation rules) Special forms ADT per expressions An abstraction barrier Used by all evaluators Parser substitution values

2 Subt. model interpreter: The testing mechanism Tests package: Should be run with every modification! The procedure test: Receives a single expression, e, and an expected value, v. Returns #t if and only if e evaluates to v. The procedure run-tests: Runs multiple number test expressions (test (derive-eval ‘(* 3 4)) => ‘(value 12)) (run-tests (test (derive-eval ‘(+ 3 4)) => ‘(value 7)) (test (derive-eval ‘(- 3 4)) => ‘(value -1)) (test (derive-eval ‘(/ 4 2)) => ‘(value 2))) (run-tests (test (derive-eval ‘(+ 3 4)) => ‘(value 7)) (test (derive-eval ‘(- 3 4)) => ‘(value -1)) (test (derive-eval ‘(/ 4 2)) => ‘(value 2)))

3 applicative -eval apply- procedure substituterename (define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp) (let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp))))) (define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp) (let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp))))) (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure))))) (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure))))) Subt. model interpreter: The core - components Core main-loop:

4 1.( (lambda(x) 2. (lambda(y) (y x))) 3. (lambda(x) (+ x y)) ) 1.( (lambda(x) 2. (lambda(y) (y x))) 3. (lambda(x) (+ x y)) ) Subt. model interpreter: The core – components The problem: (lambda(y) (y (lambda(x) (+ x y)))) (lambda(y) (y (lambda(x) (+ x y)))) y in line 2 is bound. y in line 3 is free. The free occurrence of y is now bound by the formal parameter. 1.( (lambda(x) 2. (lambda(y1) (y1 x))) 3. (lambda(x) (+ x y)) ) 1.( (lambda(x) 2. (lambda(y1) (y1 x))) 3. (lambda(x) (+ x y)) ) (lambda(y1) (y (lambda(x) (+ x y)))) (lambda(y1) (y (lambda(x) (+ x y)))) The solution: consistently rename bound occurrences and their binding instances: A reminder: Why do we need renaming?

5 Subt. model interpreter: The core – special forms 5 Supporting case expressions –syntax: ASP Derived expressions Core Data structures OR predicate + AND Consequence-exprs: Ordered. (case ( ). (else )) (case ( ). (else ))

6 Subt. model interpreter: The core – special forms 6 (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2))))))) (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2))))))) Supporting case expressions – usage example: control clauses last clause What are the components of a case expressions? What are the components of a case-clause? ASP Derived expressions Core Data structures

(define eval-special-form (lambda (exp) (cond ((quoted? exp) (make-value exp)) ((lambda? exp) (eval-lambda exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) ((begin? exp) (eval-begin exp)) ((case? exp) (eval-case exp))))) (define eval-special-form (lambda (exp) (cond ((quoted? exp) (make-value exp)) ((lambda? exp) (eval-lambda exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) ((begin? exp) (eval-begin exp)) ((case? exp) (eval-case exp))))) 7 Subt. model interpreter: The core – special forms Supporting case expressions as a special form Step 1: call the appropriate special evaluation procedure (define special-form? (lambda (exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (case? exp)))) (define special-form? (lambda (exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (case? exp)))) Step 2: Identify the expression as a special form ASP Derived expressions Core Data structures

Determining the evaluation rule for a case expression: 1.Evaluate the control. 2.Compare its value against compared components by order (assume numerical values). 3.Evaluate the actions of the 1 st clause where the compared value equals the control value. 4.If no such clause exists, evaluate the actions of the else-clause by order. 8 Subt. model interpreter: The core – special forms Step 3: Write the relevant special evaluation procedure Supporting case expressions as a special form (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…) (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…)

9 Subt. model interpreter: The core – special forms (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…) (define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…) Step 3: Write the relevant special evaluation procedure (define (eval-case exp) (letrec ((eval-clauses (lambda (control clauses) (cond ((null? clauses) 'unspecified) ((or (case-last-clause? clauses) (= (app-eval (case-compared (case-first-clause clauses))) control)) (eval-sequence (case-actions (case-first-clause clauses)))) (else (eval-clauses control (case-rest-clauses clauses))))))) (eval-clauses (applicative-eval (case-control exp)) (case-clauses exp)))) (define (eval-case exp) (letrec ((eval-clauses (lambda (control clauses) (cond ((null? clauses) 'unspecified) ((or (case-last-clause? clauses) (= (app-eval (case-compared (case-first-clause clauses))) control)) (eval-sequence (case-actions (case-first-clause clauses)))) (else (eval-clauses control (case-rest-clauses clauses))))))) (eval-clauses (applicative-eval (case-control exp)) (case-clauses exp)))) Supporting case expressions as a special form

10 ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ; Signature: lambda?(exp) ; Type: [T -> Boolean] ; Signature: lambda?(exp) ; Type: [T -> Boolean] Example: ADT and implementation for lambda expressions ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] (define make-lambda (lambda (parameters body) (attach-tag (cons parameters body) 'lambda))) ; Signature: make-lambda(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] (define make-lambda (lambda (parameters body) (attach-tag (cons parameters body) 'lambda))) ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] (define lambda-parameters (lambda (exp) (car (get-content exp)))) ; Signature: lambda-parameters(exp) ; Type: [LIST -> LIST(Symbol)] (define lambda-parameters (lambda (exp) (car (get-content exp)))) ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] (define lambda-body (lambda (exp) (cdr (get-content exp)))) ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] (define lambda-body (lambda (exp) (cdr (get-content exp)))) ; Signature: lambda?(exp) ; Type: [T -> Boolean] (define lambda? (lambda (exp) (tagged-by? exp 'lambda))) ; Signature: lambda?(exp) ; Type: [T -> Boolean] (define lambda? (lambda (exp) (tagged-by? exp 'lambda))) ASP Derived expressions Core Data structures Subt. model interpreter: The Abstract Syntax Parser (ASP)

11 Subt. model interpreter: The Abstract Syntax Parser (ASP) 11 ADT for case expressions (including ADT for case-clause): make-case(control case-clauses) Type: [Symbol*LIST -> CASE-Expression] make-case(control case-clauses) Type: [Symbol*LIST -> CASE-Expression] Constructor for case case?(exp) Type: [T -> Boolean] case?(exp) Type: [T -> Boolean] Predicate case-clauses(case-exp) Type: [CASE-Expression -> LIST] case-clauses(case-exp) Type: [CASE-Expression -> LIST] case-control(case-exp) Type: [CASE-Expression -> Symbol] case-control(case-exp) Type: [CASE-Expression -> Symbol] Selectors make-case-clause(compared actions) Type: [T*LIST -> CLAUSE-Expression] make-case-clause(compared actions) Type: [T*LIST -> CLAUSE-Expression] Constructor for case-clause Case-last-clause? Predicate case-actions Case-compared Selectors case-first-clause case-rest-clauses Usage example (client side): (make-case 'n (list (make-case-clause '0 '(0)) (make-case-clause '1 '(1)) (make-case-clause 'else '(+ (fib (- n 1)) (fib (– n 2)))))) (make-case 'n (list (make-case-clause '0 '(0)) (make-case-clause '1 '(1)) (make-case-clause 'else '(+ (fib (- n 1)) (fib (– n 2))))))

(define case? (lambda (exp) (tagged-by? exp 'case))) (define case? (lambda (exp) (tagged-by? exp 'case))) (define make-case-clause (lambda (compared actions) (cons compared actions))) (define make-case-clause (lambda (compared actions) (cons compared actions))) (define make-case (lambda (control case-clauses) (attach-tag (cons control case-clauses) 'case))) (define make-case (lambda (control case-clauses) (attach-tag (cons control case-clauses) 'case))) (define case-control (lambda (case-exp) (car (get-content case-exp)))) (define case-control (lambda (case-exp) (car (get-content case-exp)))) (define case-clauses (lambda (case-exp) (cdr (get-content case-exp)))) (define case-clauses (lambda (case-exp) (cdr (get-content case-exp)))) (define case-compared car) (define case-actions cdr) (define case-first-clause (lambda (clauses) (car clauses))) (define case-first-clause (lambda (clauses) (car clauses))) (define case-rest-clauses (lambda (clauses) (cdr clauses))) (define case-rest-clauses (lambda (clauses) (cdr clauses))) (define case-last-clause? (lambda (clauses) (and (null? (cdr clauses)) (eq? (case-compared (case-first-clause clauses)) 'else)))) (define case-last-clause? (lambda (clauses) (and (null? (cdr clauses)) (eq? (case-compared (case-first-clause clauses)) 'else)))) 12 Adding the implementation of the ADT: Constructor Selectors Predicate Subt. model interpreter: The Abstract Syntax Parser (ASP)

13 Subt. model interpreter: Derived expressions Example: deriving a case expression (case e (1 (doSomething)) (2 (* e 2)) (else e)) (case e (1 (doSomething)) (2 (* e 2)) (else e)) (if (= e 1) (doSomething) (if (= e 2) (* e 2) e)) (if (= e 1) (doSomething) (if (= e 2) (* e 2) e)) Any problem? (let ((ex e)) (if (= ex 1) (doSomething) (if (= ex 2) (* ex 2) ex))) (let ((ex e)) (if (= ex 1) (doSomething) (if (= ex 2) (* ex 2) ex)))

14 Subt. model interpreter: Derived expressions ASP Derived expressions Core Data structures Shallow- derive derive Recursively applies shallow-derive Derive? How? 1.Edit Derive? to consider the new exp as derived. 2.Edit Shallow-derive to call the relevant translation procedure. 3.Add a shallow translation procedure. Identifies the derived expression, calls the appropriate shallow translation procedure: ((cond? exp) (cond->if exp)) ⁞ ((let? exp) (let->combination exp)) Why? Smaller, simpler core! (let ((x 1)) x)  ((lambda(x) x) 1)

15 (define derive (lambda (exp) (if (atomic? exp) exp (let ((derived-exp (let ((mapped-derive-exp (map derive exp))) (if (not (derived? exp)) mapped-derive-exp (shallow-derive mapped-derive-exp))))) (if (equal? exp derived-exp) exp (derive derived-exp)))))) (define derive (lambda (exp) (if (atomic? exp) exp (let ((derived-exp (let ((mapped-derive-exp (map derive exp))) (if (not (derived? exp)) mapped-derive-exp (shallow-derive mapped-derive-exp))))) (if (equal? exp derived-exp) exp (derive derived-exp)))))) Subt. model interpreter: Derived expressions (define derived? (lambda (exp) (or (cond? exp) (function-definition? exp) (let? exp) (letrec? exp)))) (define derived? (lambda (exp) (or (cond? exp) (function-definition? exp) (let? exp) (letrec? exp)))) (define shallow-derive (lambda (exp) (cond ((cond? exp) (cond->if exp)) ((function-definition? exp) (function-define->define exp)) ((let? exp) (let->combination exp)) ((letrec? exp) (letrec->let exp)) (else "Unhandled derivision" exp)))) (define shallow-derive (lambda (exp) (cond ((cond? exp) (cond->if exp)) ((function-definition? exp) (function-define->define exp)) ((let? exp) (let->combination exp)) ((letrec? exp) (letrec->let exp)) (else "Unhandled derivision" exp))))

16 ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ; Signature: lambda-body(exp) ; Type: [LIST -> LIST] ADT for the procedure data-structure (closure) : ; Signature: make-procedure(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: make-procedure(parameters, body) ; Type: [LIST(Symbol)*LIST -> LIST] ; Signature: procedure-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: procedure-parameters(exp) ; Type: [LIST -> LIST(Symbol)] ; Signature: Compound-procedure?(exp) ; Type: [T -> Boolean] ; Signature: Compound-procedure?(exp) ; Type: [T -> Boolean] ASP Derived expressions Core Data structures Subt. model interpreter: Data Structures

17 Subt. model interpreter: Data Structures The Global Environment: A substitution between variables and values. (define make-the-global-environment (lambda () (let* ((primitive-procedures (list (list ‘car car) (list ‘cdr cdr) (list ‘cons cons) (list ‘null? null?) (list ‘+ +) (list ‘* *) (list ‘/ /) (list ‘> >) ;more primitives… )) (prim-variables (map car primitive-procedures)) (prim-values (map (lambda (x) (make-primitive-procedure (cadr x))) primitive-procedures))) (make-sub prim-variables prim-values)) )) (define make-the-global-environment (lambda () (let* ((primitive-procedures (list (list ‘car car) (list ‘cdr cdr) (list ‘cons cons) (list ‘null? null?) (list ‘+ +) (list ‘* *) (list ‘/ /) (list ‘> >) ;more primitives… )) (prim-variables (map car primitive-procedures)) (prim-values (map (lambda (x) (make-primitive-procedure (cadr x))) primitive-procedures))) (make-sub prim-variables prim-values)) )) ASP Derived expressions Core Data structures

18 Subt. model interpreter: Data Structures Getting the value of a variable in the GE: Implemented as a look-up procedure. (define get-value-of-variable (lambda (sub var) (letrec ((lookup (lambda (vars vals) (cond ((or (empty-sub sub) (not (member var vars))) (error ‘get-value-of-variable…)) ((eq? var (car vars)) (car vals)) (else (lookup (cdr vars) (cdr vals))))))) (lookup (get-variables sub) (get-values sub))))) (define get-value-of-variable (lambda (sub var) (letrec ((lookup (lambda (vars vals) (cond ((or (empty-sub sub) (not (member var vars))) (error ‘get-value-of-variable…)) ((eq? var (car vars)) (car vals)) (else (lookup (cdr vars) (cdr vals))))))) (lookup (get-variables sub) (get-values sub))))) ASP Derived expressions Core Data structures

19 Subt. model interpreter: Data Structures The substitution ADT: (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitution-application-to-expr (lambda (sub expr) (cond ((empty-sub? sub) expr) ((or (number? expr) (boolean? expr) (quoted? expr)) expr) (else (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((variable? expr) (if (member expr vars) (get-value-of-variable sub expr (lambda () expr)) expr)) ; a list of expressions, lambda, application, cond. (else (map (lambda (e) (substitute e vars values)) expr)))))) )) (define substitution-application-to-expr (lambda (sub expr) (cond ((empty-sub? sub) expr) ((or (number? expr) (boolean? expr) (quoted? expr)) expr) (else (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((variable? expr) (if (member expr vars) (get-value-of-variable sub expr (lambda () expr)) expr)) ; a list of expressions, lambda, application, cond. (else (map (lambda (e) (substitute e vars values)) expr)))))) ))

20 Subt. model interpreter: Data Structures The substitution ADT: (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitute (lambda (expr variables values) (if (evaluator-value? expr) (substitution-application-to-value (make-sub variables values) expr) (substitution-application-to-expr (make-sub variables values) expr)) )) (define substitution-application-to-value (lambda (sub val-expr) (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((primitive-procedure? val-expr) val-expr) ((value? val-expr) (if (atomic? (value-content val-expr)) val-expr (make-value (map (lambda (e) (substitute e vars values)) (value-content val-expr))))) ((compound-procedure? val-expr) (make-procedure (procedure-parameters val-expr) (map (lambda (e) (substitute e vars values)) (procedure-body val-expr)))))) )) (define substitution-application-to-value (lambda (sub val-expr) (let ((vars (get-variables sub)) (values (get-values sub))) (cond ((primitive-procedure? val-expr) val-expr) ((value? val-expr) (if (atomic? (value-content val-expr)) val-expr (make-value (map (lambda (e) (substitute e vars values)) (value-content val-expr))))) ((compound-procedure? val-expr) (make-procedure (procedure-parameters val-expr) (map (lambda (e) (substitute e vars values)) (procedure-body val-expr)))))) ))