-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtyped-iswim-ch15.rkt
139 lines (122 loc) · 3.39 KB
/
typed-iswim-ch15.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#lang racket
(require "compiled/chapter-16_rkt.zo")
(define-extended-language t-iswim iswim
(M X (λ X T M) (M M) b (o2 M M) (o1 M))
(V b X (λ X T M))
((T S) (-> T T) num)
(Γ ((X T) ...)))
(define t-iswim-red
(reduction-relation
t-iswim
(--> (in-hole E ((λ X T M) V))
(in-hole E (t-subst M X V))
βv)
(--> (in-hole E (o b ...))
(in-hole E (δ (o b ...)))
δ)))
(define-metafunction t-iswim
t-subst : any X any -> any
;; 1. X_1 bound, so don't continue in λ body
[(t-subst (λ X_1 T any_1) X_1 any_2)
(λ X_1 T any_1)]
;; 2. do capture-avoiding substitution
;; by generating a fresh name
[(t-subst (λ X_1 T any_1) X_2 any_2)
(λ X_3 T
(t-subst (t-subst-var any_1 X_1 X_3) X_2 any_2))
(where X_3 (variable-not-in (term (X_2 any_1 any_2))
(term X_1)))]
;; 3. replace X_1 with any_1
[(t-subst X_1 X_1 any_1) any_1]
;; the last two cases just recur on
;; the tree structure of the term
[(t-subst (any_2 ...) X_1 any_1)
((t-subst any_2 X_1 any_1) ...)]
[(t-subst any_2 X_1 any_1) any_2])
(define-metafunction t-iswim
t-subst-var : any X Y -> any
[(t-subst-var (any_1 ...) variable_1 variable_2)
((t-subst-var any_1 variable_1 variable_2) ...)]
[(t-subst-var variable_1 variable_1 variable_2) variable_2]
[(t-subst-var any_1 variable_1 variable_2) any_1])
(define-metafunction t-iswim
Β : any -> num or #f
[(Β number) num]
[(Β any) #f]
)
(define-metafunction t-iswim
Δ : any -> num or (-> num (-> num num)) or #f
[(Δ (iszero num)) (-> num (-> num num))]
[(Δ (add1 num)) num]
[(Δ (sub1 num)) num]
[(Δ (+ num num)) num]
[(Δ (- num num)) num]
[(Δ (* num num)) num]
[(Δ (/ num num)) num]
[(Δ (** num num)) num]
[(Δ any) #f]
)
(define-metafunction t-iswim
TC : ((X T) ...) M -> T or #f
[(TC Γ b)
(Β b)]
[(TC Γ X)
(TCvar Γ X)]
[(TC ((Y S) ...) (λ X T M))
(TCλ T (TC ((Y S) ... (X T)) M))]
[(TC Γ (M N))
(TCapp (TC Γ M) (TC Γ N))]
[(TC Γ (o M ...))
(TCo (o (TC Γ M) ...))])
(define-metafunction t-iswim
TCvar : ((X T) ...) X -> T or #f
[(TCvar ((X T_1) ... (Y T_2) (Z T_3) ...) Y)
T_2
(side-condition (not (member (term Y) (term (Z ...)))))]
[(TCvar Γ X) #f])
(define-metafunction t-iswim
TCλ : T any -> (-> T S) or #f
[(TCλ T S) (-> T S)]
[(TCλ T #f) #f])
(define-metafunction t-iswim
TCapp : any any -> T or #f
[(TCapp (-> S T) S) T]
[(TCapp any_1 any_2) #f])
(define-metafunction t-iswim
TCo : (o any ...) -> T or #f
[(TCo (o T ...)) (Δ (o T ...))]
[(TCo (o any ...)) #f])
(define testTC
(lambda ()
(test-equal
(term (TC () ((λ x (-> num num) x) 5)))
(term #f))
(test-equal
(term (TC () (+ x y)))
(term #f))
(test-equal
(term (TC () (+ 1 2)))
(term num))
(test-equal
(term (TC () (((λ x num (λ y num x)) 2) 3)))
(term num))
(test-equal
(term (TC () ((λ x num 2) 4)))
(term num))
(test-equal
(term (TC () (+ ((λ x num x) 1) 2)))
(term num))
(test-results)))
(define testProg
(λ ()
(test-->> t-iswim-red
(term ((λ x num 2) 4)) 2)
(test-->> t-iswim-red
(term (((λ x num (λ y num x)) 2) 3)) 2)
(test-->> t-iswim-red
(term (+ ((λ x num x) 1) 2)) 3)
(test-results)))
(define all-tests
(λ ()
(testTC)
(testProg)))