-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathex-stlc.scm
84 lines (79 loc) · 2.51 KB
/
ex-stlc.scm
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
(define-rel
(!-o gamma expr type)
((!-o-clause-i !-o) (!-o-full-clause-i !-o lookupo))
(rule-case)
(matche (expr type)
((,x ,T) (symbolo x) (lookupo `(,x : ,T) gamma)
(== rule-case 'var))
(((lambda (,x) ,e) (,T1 -> ,T2))
(!-o `((,x : ,T1) . ,gamma) e T2)
(== rule-case 'abs))
(((,e1 ,e2) ,T)
(fresh (T1)
(!-o gamma e1 `(,T1 -> ,T))
(!-o gamma e2 T1))
(== rule-case 'app))))
(define-rel
(!!-o gamma expr type)
((!!-o-clause-i !!-o) (!!-o-full-clause-i !!-o lookupo))
(rule-case)
(matche (expr type)
((#t boolean)
(== rule-case 'true))
((#f boolean)
(== rule-case 'false))
((,num integer) (numbero num)
(== rule-case 'num))
(((car ,e) ,T1) (fresh (T2) (!!-o gamma e `(,T1 X ,T2)))
(== rule-case 'car))
(((cdr ,e) ,T2) (fresh (T1) (!!-o gamma e `(,T1 X ,T2)))
(== rule-case 'cdr))
(((cons ,e1 ,e2) (,T1 X ,T2))
(!!-o gamma e1 T1)
(!!-o gamma e2 T2)
(== rule-case 'cons))
((,x ,T) (symbolo x) (lookupo `(,x : ,T) gamma)
(== rule-case 'var))
(((lambda (,x) ,e) (,T1 -> ,T2))
(!!-o `((,x : ,T1) . ,gamma) e T2)
(== rule-case 'abs))
(((,e1 ,e2) ,T)
(fresh (T1)
(!!-o gamma e1 `(,T1 -> ,T))
(!!-o gamma e2 T1))
(== rule-case 'app))
(((if ,e1 ,e2 ,e3) ,T)
(!!-o gamma e1 'boolean)
(!!-o gamma e2 T)
(!!-o gamma e3 T)
(== rule-case 'if))))
(define (lookupo binding gamma)
(matche (binding gamma)
(((,x : ,v) ((,x : ,v) . ,_)))
(((,x : ,v) ((,y : ,_) . ,gamma1)) (=/= x y) (lookupo binding gamma1))))
(define (to-clause clause-i)
(lambda (head tail)
(fresh (rule-case)
(clause-i head tail rule-case))))
(define !-o-clause (to-clause !-o-clause-i))
(define !!-o-clause (to-clause !!-o-clause-i))
(define (to-clause-case clause-i)
(lambda (head tail rule-case)
(clause-i head tail rule-case)))
(define !-o-clause-case (to-clause-case !-o-clause-i))
(define !!-o-clause-case (to-clause-case !!-o-clause-i))
(define (to-debug-clause-case full-clause-i)
(lambda (head tail rule-case)
(conde
((full-clause-i head tail rule-case))
((== tail '())
(== rule-case '())
(conde
((fresh (binding rho)
(== `(lookupo ,binding ,rho) head)
(lookupo binding rho)))
((fresh (x y)
(== `(== ,x ,y) head)
(== x y))))))))
(define !-o-debug-clause-case (to-debug-clause-case !-o-full-clause-i))
(define !!-o-debug-clause-case (to-debug-clause-case !!-o-full-clause-i))