Skip to content

Commit 06b8b0b

Browse files
committed
added a dependent type checker from Thierry Coquand
1 parent 37c3a21 commit 06b8b0b

File tree

2 files changed

+135
-1
lines changed

2 files changed

+135
-1
lines changed

boolean-simp.ss

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
;---------------------------------------------
66
;; (1) Push 'and' into 'or'
7-
;; (2) Push 'not' into 'and' or 'or'
7+
;; (2) Push 'not' into 'and' and 'or'
88
;; Do (1) and (2) recursively until no more simplification can be made
99
(define simpl
1010
(lambda (exp)
@@ -41,6 +41,10 @@
4141
(lambda (ct)
4242
(lambda (exp)
4343
(match exp
44+
[`(and ,a ,a)
45+
(list a)]
46+
[`(or ,a ,a)
47+
(list a)]
4448
[`(and ,x* ...)
4549
(let ([y* (apply append (map (combine1 'and) x*))])
4650
(if (eq? 'and ct) y* `((and ,@y*))))]
@@ -91,3 +95,10 @@
9195
(simplify '(not (and (not a) (not (and b c)))))
9296

9397
;; ==> '(or a (and b c))
98+
99+
100+
;---------------------------------------------
101+
(simplify '(and (or a b) (or a c)))
102+
103+
;; ==> '(or (and a c) (and a d) (and b c) (and b d))
104+

conv1.hs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
-- Type checker for dependent types from Thierry Coquand:
2+
-- http://www.cse.chalmers.se/~coquand/conv1.hs
3+
-- added some comments to ease understanding
4+
5+
6+
type Id = String
7+
8+
data Exp = Var Id
9+
| App Exp Exp
10+
| Type
11+
| Abs Id Exp
12+
| Pi Id Exp Exp
13+
| Let Id Exp Exp Exp
14+
15+
data Val = VGen Int
16+
| VApp Val Val
17+
| VType
18+
| VAbs FVal
19+
| VPi Val FVal
20+
21+
22+
type FVal = (Id,Exp,Env)
23+
type Env = [(Id,Val)]
24+
25+
26+
update :: Env -> Id -> Val -> Env
27+
update env x u = (x,u):env
28+
29+
30+
lookUp :: Id -> Env -> Val
31+
lookUp x ((y,u):env) =
32+
if x == y then u
33+
else lookUp x env
34+
lookUp x [] = error"lookUp"
35+
36+
37+
38+
-- the whnf algorithm
39+
40+
fapp :: FVal -> Val -> Val
41+
fapp (x,e,env) u = eval (update env x u) e
42+
43+
44+
app :: Val -> Val -> Val
45+
app (VAbs f) = fapp f -- can reduce with beta-reduction
46+
app v = VApp v -- cannot reduce any further, so store it as value
47+
48+
49+
eval :: Env -> Exp -> Val
50+
eval env e = case e of
51+
Var x -> lookUp x env
52+
App e1 e2 -> app (eval env e1) (eval env e2)
53+
Let x e1 _ e3 -> eval (update env x (eval env e1)) e3
54+
Type -> VType
55+
Abs x e1 -> VAbs (x,e1,env)
56+
Pi x a b -> VPi (eval env a) (x,b,env) -- evaluate the type annotation
57+
58+
59+
60+
-- the conversion algorithm; the integer is
61+
-- used to represent the introduction of a fresh variable
62+
-- VGen == gensym. seems to have a problem because k is not used as a
63+
-- state.
64+
65+
eqVal :: (Int,Val,Val) -> Bool
66+
eqVal (k,u1,u2) =
67+
case (u1,u2) of
68+
(VType,VType) -> True
69+
(VApp t1 w1,VApp t2 w2) -> eqVal (k,t1,t2) && eqVal (k,w1,w2)
70+
(VGen k1,VGen k2) -> k1 == k2
71+
(VAbs f1,VAbs f2) ->
72+
let v = VGen k
73+
in eqVal (k+1,fapp f1 v,fapp f2 v)
74+
(VPi w1 f1,VPi w2 f2) ->
75+
let v = VGen k
76+
in eqVal (k,w1,w2) && eqVal (k+1,fapp f1 v,fapp f2 v)
77+
_ -> False
78+
79+
80+
81+
------------------ type-checking and type inference ---------------------
82+
83+
-- top level: check that expression e has the type VType
84+
checkType :: (Int,Env,Env) -> Exp -> Bool
85+
checkType (k,rho,gamma) e = checkExp (k,rho,gamma) e VType
86+
87+
88+
89+
-- check an expression (e) against a type (v)
90+
checkExp :: (Int,Env,Env) -> Exp -> Val -> Bool
91+
checkExp (k,rho,gamma) e v =
92+
case (e,v) of
93+
(Abs x e1,VPi w f) ->
94+
let v = VGen k
95+
in checkExp (k+1,update rho x v,update gamma x w) e1 (fapp f v)
96+
(Pi x a b,VType) ->
97+
checkType (k,rho,gamma) a &&
98+
checkType (k+1,update rho x (VGen k),update gamma x (eval rho a)) b
99+
(Let x e1 e2 e3,v) ->
100+
checkType (k,rho,gamma) e1 &&
101+
let v1 = eval rho e1
102+
in checkExp (k,rho,gamma) e2 v1 &&
103+
checkExp (k,update rho x (eval rho e1),update gamma x (eval rho e2)) e3 v
104+
_ -> eqVal (k, inferExp (k,rho,gamma) e, v)
105+
106+
107+
108+
109+
-- synthesis a type from expression
110+
inferExp :: (Int,Env,Env) -> Exp -> Val
111+
inferExp (k,rho,gamma) e =
112+
case e of
113+
Var id -> lookUp id gamma
114+
App e1 e2 ->
115+
case (inferExp (k,rho,gamma) e1) of
116+
VPi w f ->
117+
if checkExp (k,rho,gamma) e2 w
118+
then fapp f (eval rho e2)
119+
else error"application error"
120+
_ -> error"application, expected Pi"
121+
Type -> VType
122+
_ -> error"cannot infer type"
123+

0 commit comments

Comments
 (0)