---
tags: mp, WCh
---
# Lista 8
## boolean.rkt
```racket=
#lang racket
; Do let-env.rkt dodajemy wartosci boolowskie
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))] ; <----------------- !!!
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef) ; <--------------------------------------- !!!
(and (expr? eb) (expr? et) (expr? ef))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)] ; <---------------------------- !!!
[(eq? q 'false) (const false)] ; <---------------------------- !!!
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if)) ; <--- !!!
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (test-parse) (parse '(let [x (+ 2 2)] (+ x 1))))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v) (boolean? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo] ; <----------- !!!
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env) ; <----------------- !!!
(eval-env et env)
(eval-env ef env))]))
(define (eval e) (eval-env e env-empty))
(define program
'(if (or (< (% 123 10) 5)
true)
(+ 2 3)
(/ 2 0)))
(define (test-eval) (eval (parse program)))
```
## Ćwiczenie 1
```racket=
#lang racket
; Do let-env.rkt dodajemy wartosci boolowskie
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (eq? n 'true) (eq? n 'false))] ; <---------- zad1
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef) ; <--------------------------------------- !!!
(and (expr? eb) (expr? et) (expr? ef))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const 'true)] ; <---------- zad1
[(eq? q 'false) (const 'false)] ; ; <---------- zad1
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if)) ; <--- !!!
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (test-parse) (parse '(let [x (+ 2 2)] (+ x 1))))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
; Bierze funkcję zwracającą #t/#f.
; Zwraca funkcję zwracającą 1/0.
(define (to-01 fn)
(lambda (x y)
(if (fn x y) 1 0)))
; ['= (to-01 =)] ['> (to-01 >)] ['>= (to-01 >=)] ['< (to-01 <)] ['<= (to-01 <=)]
(define (value? v)
(or (number? v) (boolean? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo] ; <----------- !!!
['= (lambda (x y) (if (= x y) 1 0))]
['> (lambda (x y) (if (> x y) 1 0))]
['>= (lambda (x y) (if (>= x y) 1 0))]
['< (lambda (x y) (if (< x y) 1 0))]
['<= (lambda (x y) (if (<= x y) 1 0))]
['and (lambda (x y) (if (and (= x 1) (= y 1)) 1 0))]
['or (lambda (x y) (if (or (= x 1) (= y 1)) 1 0))]))
(define (eval-env e env)
(match e
[(const n) (cond ; <---------- zad1
[(eq? n 'false) 0]
[(eq? n 'true) 1]
[else n])]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (= (eval-env eb env) 0) ; <---------- zad1
(eval-env ef env)
(eval-env et env))]))
(define (eval e) (eval-env e env-empty))
; powinien dać 1/0
(define program
'(if (or (> (% 123 10) 5)
false)
(+ 2 3)
(/ 2 0)))
(define (test-eval) (eval (parse program)))
```
```
> (parse '(if 0 false true))
(if-expr (const 0) (const 'false) (const 'true))
```
```
; powinien dać 1/0
(define program
'(if (= 1 2)
(+ 2 3)
(/ 2 1)))
> (eval (parse program))
2
```
## Ćwiczenie 2
>Żeby zrobić jako formy specjalne to zamiast unop trzeba zrobić osobne
structy dla boolean? i number? i odpowiednio zmodyfikowac expr? eval
op->proc (Tam gdzie unop)
```racket=
#lang racket
; Do let-env.rkt dodajemy wartosci boolowskie
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct unop (op e) #:transparent) ; <--- zmiana
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(unop op e) (and (expr? e) (symbol? op))] ;---> zmiana
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (symbol? (first q))) (unop (first q) (parse (second q)))] ;<----- ZMIANA
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (test-parse) (parse '(let [x (+ 2 2)] (+ x 1))))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v) (boolean? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
['boolean? boolean?] ['number? number?])) ;----> zmiana
(define (eval-env e env)
(match e
[(const n) n]
[(unop op e) ((op->proc op) (eval-env e env))] ;-> zmiana
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env) ;
(eval-env et env)
(eval-env ef env))]))
(define (eval e) (eval-env e env-empty))
(define program
'(if (or (< (% 123 10) 5)
true)
(+ 2 3)
(/ 2 0)))
(define (test-eval) (eval (parse program)))
(eval (parse '(number? (if (< 0 (+ (* 2 2) 7)) 5 true)))) ;-> #t
(eval (parse '(boolean? (if (< 0 (+ (* 2 2) 7)) 5 true)))) ;-> #f
(eval (parse '(boolean? (if (> 0 (+ (* 2 2) 7)) 5 true)))) ;-> #t
```
## Ćwiczenie 3
```racket=
#lang racket
; Do let-env.rkt dodajemy wartosci boolowskie
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct binop2 (op l r) #:transparent)
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (eq? n 'true) (eq? n 'false))] ; <---------- zad1
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef) ; <--------------------------------------- !!!
(and (expr? eb) (expr? et) (expr? ef))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const 'true)] ; <---------- zad1
[(eq? q 'false) (const 'false)] ; ; <---------- zad1
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if)) ; <--- !!!
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (or (eq? (first q) 'and) (eq? (first q) 'or) ) )
(binop2 (first q)
(parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (test-parse) (parse '(let [x (+ 2 2)] (+ x 1))))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v) (boolean? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo] ; <----------- !!!
['= (lambda (x y) (if (= x y) 1 0))]
['> (lambda (x y) (if (> x y) 1 0))]
['>= (lambda (x y) (if (>= x y) 1 0))]
['< (lambda (x y) (if (< x y) 1 0))]
['<= (lambda (x y) (if (<= x y) 1 0))]
))
(define (zmien x)
(if (= x 0) false true)
)
(define (spowrotem x)
(if x 1 0)
)
;; spowrotem -> z-powrotem
(define (eval-env e env)
(match e
[(const n) (cond ; <---------- zad1
[(eq? n 'false) 0]
[(eq? n 'true) 1]
[else n])]
[(binop2 op l r) (cond [(eq? op 'and) (spowrotem (and (zmien (eval-env l env )) (zmien (eval-env r env)))) ]
[(eq? op 'or) (spowrotem (or (zmien (eval-env l env)) (zmien (eval-env r env)))) ]
)]
; [(binop 'and l r) (spowrotem (and (zmien (eval-env l env )) (zmien (eval-env r env))))]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (= (eval-env eb env) 0) ; <---------- zad1
(eval-env ef env)
(eval-env et env))]))
(define (eval e) (eval-env e env-empty))
(define program
'(if (or (> (% 123 10) 5)
false)
(+ 2 3)
(/ 2 0)))
(define (test-eval) (eval (parse program)))
```
można było też potraktować and i or jako lukier syntaktyczny i zmienić na if w trakcie parsowania:
``` racket==
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'and)); <----------------- !!!
(if-expr (parse (second q))
(parse (third q))
(const false))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'or)); <----------------- !!!
(if-expr (parse (second q))
(const 'true)
(parse (third q)))]
```
## Ćwiczenie 4
```racket=
#lang racket
; Do boolean.rkt dodajemy pary
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent) ; <------------------- !!!
(struct car-expr (e) #:transparent) ; <------------------- !!!
(struct cdr-expr (e) #:transparent) ; <------------------- !!!
(struct pair?-expr (e) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))] ; <----------- !!!
[(car-expr e) (expr? e)] ; <---------------------------------- !!!
[(cdr-expr e) (expr? e)] ; <---------------------------------- !!!
[(pair?-expr e) (expr? e) ]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons)) ; <- !!!
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car)) ; <-- !!!
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr)) ; <-- !!!
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'pair?))
(pair?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (test-parse) (parse '(let [x (+ 2 2)] (+ x 1))))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env) ; <---------------- !!!
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))] ; <--------------------- !!!
[(cdr-expr e) (cdr (eval-env e env))]
[(pair?-expr e) (pair? (eval-env e env))]
)) ; <------------------- !!!
(define (eval e) (eval-env e env-empty))
(define program
'(car (if true (cons 1 2) false)))
(define (test-eval) (eval (parse program)))
```
## Ćwiczenie 5
Niezrobione
```
; Z fun.rkt:
[(and (list? q) (pair? q) (not (op->proc (car q)))) ; <------- !!!
(parse-app q)]
```
```
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['pair? pair?] ; <- NOWE
['not not] ; <- NOWE
['car car] ; <- NOWE
['cdr cdr] ; <- NOWE
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
[_ false]))
```
## Ćwiczenie 6
```racket
#lang racket
; Do boolean.rkt dodajemy pary
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent) ; <------------------- !!!
(struct car-expr (e) #:transparent) ; <------------------- !!!
(struct cdr-expr (e) #:transparent) ; <------------------- !!!
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))] ; <----------- !!!
[(car-expr e) (expr? e)] ; <---------------------------------- !!!
[(cdr-expr e) (expr? e)] ; <---------------------------------- !!!
[_ false]))
(define (parse q)
(define (isCR? l)
(define (rec x) (if (or (eq? (car x) #\d) (eq? (car x) #\a))
(rec (cdr x))
(and (eq? (car x) #\r) (eq? (cdr x) null))))
(if (eq? (car l) #\c)
(rec (cdr l))
false))
(define (parseCR l rest)
(match (car l)
[#\a (car-expr (parseCR (cdr l) rest))]
[#\d (cdr-expr (parseCR (cdr l) rest))]
[#\r (parse rest)]))
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons)) ; <- !!!
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car)) ; <-- !!!
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr)) ; <-- !!!
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (isCR? (string->list (symbol->string (first q)))))
(parseCR (cdr (string->list (symbol->string (first q)))) (second q))]))
(define (test-parse) (parse '(let [x (+ 2 2)] (+ x 1))))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env) ; <---------------- !!!
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))] ; <--------------------- !!!
[(cdr-expr e) (cdr (eval-env e env))])) ; <------------------- !!!
(define (eval e) (eval-env e env-empty))
(define program
'(car (if true (cons 1 2) false)))
(define (test-eval) (eval (parse program)))
(eval (parse '(cadr (cons 1 (cons 2 3))))) ;zwraca 2
```
```
(define prog
'(let [xs (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 6)))))]
(caddddr xs)))
```
## Ćwiczenie 7
```racket=
#lang racket
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
[_ false]))
(define (parse q)
(define (desugar expr) ;; <-------------- !!!!
(if (null? expr)
(null-expr)
(cons-expr (car expr) (desugar (cdr expr)))))
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (first q) 'list)) ;; <-------------- !!!!
(desugar (map parse (cdr q)))] ;; <-------------- !!!!
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(null-expr) null]
[(null?-expr e) (null? (eval-env e env))]))
(define (eval e) (eval-env e env-empty))
```
## Ćwiczenie 8
```racket=
#lang racket
; Do pair.rkt dodajemy listy
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(struct nth-expr (selector e) #:transparent) ; <- NOWE
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
; FIXME: czy ewaluować pierwszy parametr (dla dynamicznych wyrażeń)?
[(nth-expr selector e) (and (symbol? selector) (expr? e))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)] ;
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (= (length q) 2)) ; <- NOWE
(nth-expr (first q) (parse (second q)))] ; <- NOWE
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs))
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v))) ;
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]))
(define (get-nth n xs) (list-ref xs n)) ; <- NOWE
; Pomysł: pogrupować słowa w grupy (a . modifier).
; `a` w przedziale 0-999, modifier \in {billion, million, thousand}.
(define (selector-to-n selector)
(define (a-to-number mod)
(match mod
['first 1] ['second 2] ['third 3] ['fourth 4] ['fifth 5]
['sixth 6] ['seventh 7] ['eighth 8] ['ninth 9] ['tenth 10]
['eleventh 11] ['twelfth 12] ['thirteenth 13] ['fourteenth 14] ['fifteenth 15]
['sixteenth 16] ['seventeenth 17] ['eighteenth 18] ['nineteenth 19]
; Dla one-hundred etc.
; FIXME: wydzielić do innej funkcji, żeby (one xs) nie działało.
['one 1] ['two 2] ['three 3] ['four 4] ['five 5]
['six 6] ['seven 7] ['eight 8] ['nine 9] ['ten 10]
['eleven 11] ['twelve 12] ['thirteen 13] ['fourteen 14] ['fifteen 15]
['sixteen 16] ['seventeen 17] ['eighteen 18] ['nineteen 19]
['twenty 20] ['thirty 30] ['forty 40] ['fifty 50]
['sixty 60] ['seventy 70] ['eighty 80] ['ninety 90]
[_ false]))
(define (group-separator? mod)
(match mod
['hundred false]
['thousand true]
['million true]
['billion true]
[_ false]))
(define (exp-to-number mod)
(match mod
['hundred 100]
['thousand 1000]
['million 1000000]
['billion 1000000000]
[_ false]))
(define (group-complete? group)
(and (not (null? group))
(group-separator? (car group))))
; chunks - lista symboli (słów)
; groups - lista list (grup)
; grupa to np. (first hundred one)
(define (chunks-to-groups chunks groups)
(cond
; Warunek stopu iteracji.
[(null? chunks) groups]
; Zaczynamy budować nową listę grup...
[(null? groups)
(chunks-to-groups
(cdr chunks)
(cons (cons (car chunks) null) null))]
; Zaczynamy budować nową grupę...
[(group-complete? (car groups))
(chunks-to-groups
(cdr chunks)
(cons (cons (car chunks) null) groups))]
; Kontynuujemy budowanie grupy...
[else
(chunks-to-groups
(cdr chunks)
(cons (cons (car chunks) (car groups)) (cdr groups)))]))
(define (group-to-num group)
(cond
[(null? group) 0]
[(exp-to-number (car group)) (* (exp-to-number (car group)) (group-to-num (cdr group)))]
[else (+ (a-to-number (car group)) (group-to-num (cdr group)))]))
(define chunks
(map string->symbol
(string-split
(symbol->string selector)
"-")))
(define groups
(chunks-to-groups chunks null))
(display "Groups: ")
(displayln groups)
(define numbers
(map group-to-num groups))
(display "Numbers: ")
(displayln numbers)
(define sum
(foldl + 0 numbers))
(displayln sum)
sum)
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(nth-expr selector e) (get-nth (selector-to-n selector) (eval-env e env))] ; <- NOWE
[(null-expr) null]
[(null?-expr e) (null? (eval-env e env))]))
(define (eval e) (eval-env e env-empty))
(define program
'(nine-hundred-ninety-nine-billion-nine-hundred-ninety-nine-million-nine-hundred-ninety-nine-thousand-nine-hundred-ninety-ninth nope))
(eval (parse program))
```
## Ćwiczenie 9
```racket=
#lang racket
; Do list.rkt dodajemy procedury
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(struct app (f e) #:transparent)
(struct lam (id e) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
[(app f e) (and (expr? f) (expr? e))]
[(lam id e) (and (symbol? id) (expr? e))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'lambda))
(parse-lam (second q) (third q))]
[(and (list? q) (pair? q) (not (op->proc (car q))))
(parse-app q)]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (parse-app q) ;
(define (parse-app-accum q acc)
(cond [(= 1 (length q)) (app acc (parse (car q)))]
[else (parse-app-accum (cdr q) (app acc (parse (car q))))]))
(parse-app-accum (cdr q) (parse (car q))))
(define (parse-lam pat e)
(cond [(= 1 (length pat))
(lam (car pat) (parse e))]
[else
(lam (car pat) (parse-lam (cdr pat) e))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs) #:transparent)
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(struct clo (id e env) #:transparent)
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v)
(clo? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
[_ false]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(null-expr) null]
[(null?-expr e) (null? (eval-env e env))]
[(lam x e) (clo x e env)]
[(app f e)
(let ([vf (eval-env f env)]
[ve (eval-env e env)])
(match vf [(clo x body fun-env)
(eval-env body (env-add x ve fun-env))]))]))
(define (eval e) (eval-env e env-not))
(define env-not (env-add 'not (eval-env (parse '(lambda (q) (if q
false
true))) env-empty) env-empty))
(define not-program1
'(not true))
(define not-program2
'(not false))
(define not-program3
'(not (or true false))
)
(eval (parse not-program1))
(eval (parse not-program2))
(eval (parse not-program3))
```
## Ćwiczenie 10
```racket=
#lang racket
; Do list.rkt dodajemy procedury
;
; Miejsca, ktore sie zmienily oznaczone sa przez !!!
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(struct app (f e) #:transparent)
(struct lam (id e) #:transparent)
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
[(app f e) (and (expr? f) (expr? e))]
[(lam id e) (and (symbol? id) (expr? e))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'lambda))
(parse-lam (second q) (third q))]
[(and (list? q) (pair? q) (not (op->proc (car q))))
(parse-app q)]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (parse-app q) ;
(define (parse-app-accum q acc)
(cond [(= 1 (length q)) (app acc (parse (car q)))]
[else (parse-app-accum (cdr q) (app acc (parse (car q))))]))
(parse-app-accum (cdr q) (parse (car q))))
(define (parse-lam pat e)
(cond [(= 1 (length pat))
(lam (car pat) (parse e))]
[else
(lam (car pat) (parse-lam (cdr pat) e))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs) #:transparent)
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(struct clo (id e env) #:transparent)
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v)
(clo? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
[_ false]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(null-expr) null]
[(null?-expr e) (null? (eval-env e env))]
[(lam x e) (clo x e env)]
[(app f e)
(let ([vf (eval-env f env)]
[ve (eval-env e env)])
(match vf [(clo x body fun-env)
(eval-env body (env-add x ve fun-env))]))]))
(define (eval e) (eval-env e env-embedded))
(define env-embedded (env-add 'curry
(eval-env (parse '(lambda (f)
(lambda (x y) (f (cons x y))))) env-empty)
(env-add 'uncurry
(eval-env (parse '(lambda (f)
(lambda (p) (f (car p)
(cdr p))))) env-empty)
(env-add 'not (eval-env (parse '(lambda (q) (if q
false
true))) env-empty) env-empty))))
(define not-program
'(not true)
;(not false)
;(not (or true false))
)
(eval (parse not-program))
```
> curry := (lambda (f x y) (f (cons x y)))
> uncurry := (lambda (f p) (f (car p) (cdr p)))
```
(define program3 '(let (f (lambda (p) (+ (car p) (cdr p))))
((curry f) 2 3)))
(define program4 '(let (f (lambda (x y) (+ x y)))
((uncurry f) (cons 1 2))))
[uncurry (lambda (f) (lambda (p) (f (car p) (cdr p))))]
[curry (lambda (f) (lambda (x y) (f (cons x y))))]
```
## Ćwiczenie 11
>Niezrobione
>Działa
```racket=
#lang racket
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(struct app (f e) #:transparent)
(struct lam (id e) #:transparent)
(struct let-lazy (id e1 e2) #:transparent) ; <----- NOWE
(struct min-clo (e env) #:transparent) ; <----- NOWE
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(let-lazy x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
[(app f e) (and (expr? f) (expr? e))] ;
[(lam id e) (and (symbol? id) (expr? e))]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let-lazy)) ; <---- NOWE
(let-lazy (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'lambda))
(parse-lam (second q) (third q))]
[(and (list? q) (pair? q) (not (op->proc (car q))))
(parse-app q)]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (parse-app q)
(define (parse-app-accum q acc)
(cond [(= 1 (length q)) (app acc (parse (car q)))]
[else (parse-app-accum (cdr q) (app acc (parse (car q))))]))
(parse-app-accum (cdr q) (parse (car q))))
(define (parse-lam pat e)
(cond [(= 1 (length pat))
(lam (car pat) (parse e))]
[else
(lam (car pat) (parse-lam (cdr pat) e))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs) #:transparent)
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(struct clo (id e env) #:transparent)
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v)
(clo? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
[_ false])) ;
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(let-lazy x e1 e2) ; <----- NOWE
(eval-env e2 (env-add x (min-clo e1 env) env))]
[(var-expr x) ; <---- NOWE
(let [(x-val (env-lookup x env))]
(match x-val
[(min-clo e env) (eval-env e env)]
[_ x-val]))]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(null-expr) null]
[(null?-expr e) (null? (eval-env e env))]
[(lam x e) (clo x e env)]
[(app f e)
(let ([vf (eval-env f env)]
[ve (eval-env e env)])
(match vf [(clo x body fun-env)
(eval-env body (env-add x ve fun-env))]))]))
(define (eval e) (eval-env e env-empty))
(define test1 (parse '(let-lazy [x (+ 3 5)] (+ x x))))
(eval test1)
(define test2 (parse '(let-lazy [x 5]
(let-lazy [y (+ x 3)] (let-lazy [x 0] (+ x y))))))
(eval test2)
(define test3 (parse '(let-lazy [x (/ 1 0)] 5)))
(eval test3)
```
## Ćwiczenie 12
>Cos jest nie tak
>Pewnie nawiasy xD
```racket=
#lang racket
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(struct app (f e) #:transparent)
(struct lam (id e) #:transparent)
(struct unfold (seed step) #:transparent) ; <------------------ !!!
(struct scar (expr) #:transparent) ; <------------------ !!!
(struct scdr (expr) #:transparent) ; <------------------ !!!
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
[(app f e) (and (expr? f) (expr? e))]
[(lam id e) (and (symbol? id) (expr? e))]
[(unfold seed step) (expr? seed) (expr? step) ]
[(scar expr) (expr? expr)] ; <------------------ !!!
[(scdr expr) (expr? expr)]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'unfold))
(unfold (parse (second q)) (parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'scar)) ; <------------------ !!!
(scar (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'scdr))
(scdr (parse (second q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'lambda))
(parse-lam (second q) (third q))]
[(and (list? q) (pair? q) (not (op->proc (car q))))
(parse-app q)]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (parse-app q)
(define (parse-app-accum q acc)
(cond [(= 1 (length q)) (app acc (parse (car q)))]
[else (parse-app-accum (cdr q) (app acc (parse (car q))))]))
(parse-app-accum (cdr q) (parse (car q))))
(define (parse-lam pat e)
(cond [(= 1 (length pat))
(lam (car pat) (parse e))]
[else
(lam (car pat) (parse-lam (cdr pat) e))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs) #:transparent)
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(struct clo (id e env) #:transparent)
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v)
(unfold? v) ; <------------------ !!!
(clo? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
[_ false]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(null-expr) null]
[(unfold seed step) (unfold ( eval-env seed env) (eval-env step env))]
[(scar expr) (let* ([expr (eval-env expr env)]
[step (unfold-step expr)]
[seed (unfold-seed expr)])
(car (step seed)))] ; <------------------ !!!
[(scdr expr) (let* ([expr (eval-env expr env)]
[step (unfold-step expr)]
[seed (unfold-seed expr)])
(unfold (const (cdr (step seed))) step))]
[(null?-expr e) (null? (eval-env e env))]
[(lam x e) (clo x e env)]
[(app f e)
(let ([vf (eval-env f env)]
[ve (eval-env e env)])
(match vf [(clo x body fun-env)
(eval-env body (env-add x ve fun-env))]))]))
(define (eval e) (eval-env e env-empty))
```
## Zadanie 12 wprost od WCh
```racket=
#lang racket
; --------- ;
; Wyrazenia ;
; --------- ;
(struct const (val) #:transparent)
(struct binop (op l r) #:transparent)
(struct var-expr (id) #:transparent)
(struct let-expr (id e1 e2) #:transparent)
(struct if-expr (eb et ef) #:transparent)
(struct cons-expr (e1 e2) #:transparent)
(struct car-expr (e) #:transparent)
(struct cdr-expr (e) #:transparent)
(struct null-expr () #:transparent)
(struct null?-expr (e) #:transparent)
(struct app (f e) #:transparent)
(struct lam (id e) #:transparent)
(struct unfold (seed step) #:transparent) ; <------------------ !!!
(struct scar (expr) #:transparent) ; <------------------ !!!
(struct scdr (expr) #:transparent) ; <------------------ !!!
(define (expr? e)
(match e
[(const n) (or (number? n) (boolean? n))]
[(binop op l r) (and (symbol? op) (expr? l) (expr? r))]
[(var-expr x) (symbol? x)]
[(let-expr x e1 e2)
(and (symbol? x) (expr? e1) (expr? e2))]
[(if-expr eb et ef)
(and (expr? eb) (expr? et) (expr? ef))]
[(cons-expr e1 e2) (and (expr? e1) (expr? e2))]
[(car-expr e) (expr? e)]
[(cdr-expr e) (expr? e)]
[(null-expr) true]
[(null?-expr e) (expr? e)]
[(app f e) (and (expr? f) (expr? e))]
[(lam id e) (and (symbol? id) (expr? e))]
[(unfold seed step) (expr? seed) (expr? step) ]
[(scar expr) (expr? expr)] ; <------------------ !!!
[(scdr expr) (expr? expr)]
[_ false]))
(define (parse q)
(cond
[(number? q) (const q)]
[(eq? q 'true) (const true)]
[(eq? q 'false) (const false)]
[(eq? q 'null) (null-expr)]
[(symbol? q) (var-expr q)]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'null?))
(null?-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'cons))
(cons-expr (parse (second q))
(parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'car))
(car-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'cdr))
(cdr-expr (parse (second q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'let))
(let-expr (first (second q))
(parse (second (second q)))
(parse (third q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'unfold))
(unfold (parse (second q)) (parse (third q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'scar)) ; <------------------ !!!
(scar (parse (second q)))]
[(and (list? q) (eq? (length q) 2) (eq? (first q) 'scdr))
(scdr (parse (second q)))]
[(and (list? q) (eq? (length q) 4) (eq? (first q) 'if))
(if-expr (parse (second q))
(parse (third q))
(parse (fourth q)))]
[(and (list? q) (eq? (length q) 3) (eq? (first q) 'lambda))
(parse-lam (second q) (third q))]
[(and (list? q) (pair? q) (not (op->proc (car q))))
(parse-app q)]
[(and (list? q) (eq? (length q) 3) (symbol? (first q)))
(binop (first q)
(parse (second q))
(parse (third q)))]))
(define (parse-app q)
(define (parse-app-accum q acc)
(cond [(= 1 (length q)) (app acc (parse (car q)))]
[else (parse-app-accum (cdr q) (app acc (parse (car q))))]))
(parse-app-accum (cdr q) (parse (car q))))
(define (parse-lam pat e)
(cond [(= 1 (length pat))
(lam (car pat) (parse e))]
[else
(lam (car pat) (parse-lam (cdr pat) e))]))
; ---------- ;
; Srodowiska ;
; ---------- ;
(struct environ (xs) #:transparent)
(define env-empty (environ null))
(define (env-add x v env)
(environ (cons (cons x v) (environ-xs env))))
(define (env-lookup x env)
(define (assoc-lookup xs)
(cond [(null? xs) (error "Unknown identifier" x)]
[(eq? x (car (car xs))) (cdr (car xs))]
[else (assoc-lookup (cdr xs))]))
(assoc-lookup (environ-xs env)))
; --------- ;
; Ewaluacja ;
; --------- ;
(struct clo (id e env) #:transparent)
(define (value? v)
(or (number? v)
(boolean? v)
(and (pair? v) (value? (car v)) (value? (cdr v)))
(null? v)
(unfold? v) ; <------------------ !!!
(clo? v)))
(define (op->proc op)
(match op ['+ +] ['- -] ['* *] ['/ /] ['% modulo]
['= =] ['> >] ['>= >=] ['< <] ['<= <=]
['and (lambda (x y) (and x y))]
['or (lambda (x y) (or x y))]
[_ false]))
(define (eval-env e env)
(match e
[(const n) n]
[(binop op l r) ((op->proc op) (eval-env l env)
(eval-env r env))]
[(let-expr x e1 e2)
(eval-env e2 (env-add x (eval-env e1 env) env))]
[(var-expr x) (env-lookup x env)]
[(if-expr eb et ef) (if (eval-env eb env)
(eval-env et env)
(eval-env ef env))]
[(cons-expr e1 e2) (cons (eval-env e1 env)
(eval-env e2 env))]
[(car-expr e) (car (eval-env e env))]
[(cdr-expr e) (cdr (eval-env e env))]
[(null-expr) null]
[(unfold s f) (unfold (eval-env s env) (eval-env f env))]; <------------------------ !!!
[(scar e) ; <------------------------------------------------ !!!
(match (eval-env e env)
[(unfold s (clo x body fun-env))
(car (eval-env body (env-add x s fun-env)))]
[_ (error "not a unfold")])]
[(scdr e) ; <------------------------------------------------ !!!
(match (eval-env e env)
[(unfold s (clo x body fun-env))
(unfold (cdr (eval-env body (env-add x s fun-env))) (clo x body fun-env))]
[_ (error "not a unfold")])]
[(null?-expr e) (null? (eval-env e env))]
[(lam x e) (clo x e env)]
[(app f e)
(let ([vf (eval-env f env)]
[ve (eval-env e env)])
(match vf [(clo x body fun-env)
(eval-env body (env-add x ve fun-env))]))]))
(define (eval e) (eval-env e env-empty))
```
Testy:
```
(eval (parse
'(scar (unfold 0 (lambda (x) (cons (* x x) (+ 1 x)))))))
(eval (parse
'(scar (scdr (unfold 0 (lambda (x) (cons (* x x) (+ 1 x))))))))
(eval (parse
'(scar (scdr (scdr (unfold 0 (lambda (x) (cons (* x x) (+ 1
x)))))))))
(eval (parse
'(scar (scdr (scdr (scdr (unfold 0 (lambda (x) (cons (* x x) (+ 1
x))))))))))
(eval (parse
'(scar (scdr (scdr (scdr (scdr (unfold 0 (lambda (x) (cons (* x x)
(+ 1 x)))))))))))
```