/testsuite/tests/typing-gadts/omega07.ml

http://github.com/OCamlPro/ocp-ocaml · OCaml · 800 lines · 649 code · 109 blank · 42 comment · 21 complexity · 29ded370ca7edd2540e2c26ad5bd56ef MD5 · raw file

  1. (*
  2. An attempt at encoding omega examples from the 2nd Central European
  3. Functional Programming School:
  4. Generic Programming in Omega, by Tim Sheard and Nathan Linger
  5. http://web.cecs.pdx.edu/~sheard/
  6. *)
  7. (* Basic types *)
  8. type ('a,'b) sum = Inl of 'a | Inr of 'b
  9. type zero = Zero
  10. type _ succ
  11. type _ nat =
  12. | NZ : zero nat
  13. | NS : 'a nat -> 'a succ nat
  14. ;;
  15. (* 2: A simple example *)
  16. type (_,_) seq =
  17. | Snil : ('a,zero) seq
  18. | Scons : 'a * ('a,'n) seq -> ('a, 'n succ) seq
  19. ;;
  20. let l1 = Scons (3, Scons (5, Snil)) ;;
  21. (* We do not have type level functions, so we need to use witnesses. *)
  22. (* We copy here the definitions from section 3.9 *)
  23. (* Note the addition of the ['a nat] argument to PlusZ, since we do not
  24. have kinds *)
  25. type (_,_,_) plus =
  26. | PlusZ : 'a nat -> (zero, 'a, 'a) plus
  27. | PlusS : ('a,'b,'c) plus -> ('a succ, 'b, 'c succ) plus
  28. ;;
  29. let rec length : type a n. (a,n) seq -> n nat = function
  30. | Snil -> NZ
  31. | Scons (_, s) -> NS (length s)
  32. ;;
  33. (* app returns the catenated lists with a witness proving that
  34. the size is the sum of its two inputs *)
  35. type (_,_,_) app = App : ('a,'p) seq * ('n,'m,'p) plus -> ('a,'n,'m) app
  36. let rec app : type a n m. (a,n) seq -> (a,m) seq -> (a,n,m) app =
  37. fun xs ys ->
  38. match xs with
  39. | Snil -> App (ys, PlusZ (length ys))
  40. | Scons (x, xs') ->
  41. match app xs' ys with
  42. | App (xs'', pl) -> App (Scons (x, xs''), PlusS pl)
  43. ;;
  44. (* Note: it would be nice to be able to handle existentials in
  45. let definitions *)
  46. (* 3.1 Feature: kinds *)
  47. (* We do not have kinds, but we can encode them as predicates *)
  48. type tp
  49. type nd
  50. type (_,_) fk
  51. type _ shape =
  52. | Tp : tp shape
  53. | Nd : nd shape
  54. | Fk : 'a shape * 'b shape -> ('a,'b) fk shape
  55. ;;
  56. type tt
  57. type ff
  58. type _ boolean =
  59. | BT : tt boolean
  60. | BF : ff boolean
  61. ;;
  62. (* 3.3 Feature : GADTs *)
  63. type (_,_) path =
  64. | Pnone : 'a -> (tp,'a) path
  65. | Phere : (nd,'a) path
  66. | Pleft : ('x,'a) path -> (('x,'y) fk, 'a) path
  67. | Pright : ('y,'a) path -> (('x,'y) fk, 'a) path
  68. ;;
  69. type (_,_) tree =
  70. | Ttip : (tp,'a) tree
  71. | Tnode : 'a -> (nd,'a) tree
  72. | Tfork : ('x,'a) tree * ('y,'a) tree -> (('x,'y)fk, 'a) tree
  73. ;;
  74. let tree1 = Tfork (Tfork (Ttip, Tnode 4), Tfork (Tnode 4, Tnode 3))
  75. ;;
  76. let rec find : type sh.
  77. ('a -> 'a -> bool) -> 'a -> (sh,'a) tree -> (sh,'a) path list
  78. = fun eq n t ->
  79. match t with
  80. | Ttip -> []
  81. | Tnode m ->
  82. if eq n m then [Phere] else []
  83. | Tfork (x, y) ->
  84. List.map (fun x -> Pleft x) (find eq n x) @
  85. List.map (fun x -> Pright x) (find eq n y)
  86. ;;
  87. let rec extract : type sh. (sh,'a) path -> (sh,'a) tree -> 'a = fun p t ->
  88. match (p, t) with
  89. | Pnone x, Ttip -> x
  90. | Phere, Tnode y -> y
  91. | Pleft p, Tfork(l,_) -> extract p l
  92. | Pright p, Tfork(_,r) -> extract p r
  93. ;;
  94. (* 3.4 Pattern : Witness *)
  95. type (_,_) le =
  96. | LeZ : 'a nat -> (zero, 'a) le
  97. | LeS : ('n, 'm) le -> ('n succ, 'm succ) le
  98. ;;
  99. type _ even =
  100. | EvenZ : zero even
  101. | EvenSS : 'n even -> 'n succ succ even
  102. ;;
  103. type one = zero succ
  104. type two = one succ
  105. type three = two succ
  106. type four = three succ
  107. ;;
  108. let even0 : zero even = EvenZ
  109. let even2 : two even = EvenSS EvenZ
  110. let even4 : four even = EvenSS (EvenSS EvenZ)
  111. ;;
  112. let p1 : (two, one, three) plus = PlusS (PlusS (PlusZ (NS NZ)))
  113. ;;
  114. let rec summandLessThanSum : type a b c. (a,b,c) plus -> (a,c) le = fun p ->
  115. match p with
  116. | PlusZ n -> LeZ n
  117. | PlusS p' -> LeS (summandLessThanSum p')
  118. ;;
  119. (* 3.8 Pattern: Leibniz Equality *)
  120. type (_,_) equal = Eq : ('a,'a) equal
  121. let convert : type a b. (a,b) equal -> a -> b = fun Eq x -> x
  122. let rec sameNat : type a b. a nat -> b nat -> (a,b) equal option = fun a b ->
  123. match a, b with
  124. | NZ, NZ -> Some Eq
  125. | NS a', NS b' ->
  126. begin match sameNat a' b' with
  127. | Some Eq -> Some Eq
  128. | None -> None
  129. end
  130. | _ -> None
  131. ;;
  132. (* Extra: associativity of addition *)
  133. let rec plus_func : type a b m n.
  134. (a,b,m) plus -> (a,b,n) plus -> (m,n) equal =
  135. fun p1 p2 ->
  136. match p1, p2 with
  137. | PlusZ _, PlusZ _ -> Eq
  138. | PlusS p1', PlusS p2' ->
  139. let Eq = plus_func p1' p2' in Eq
  140. let rec plus_assoc : type a b c ab bc m n.
  141. (a,b,ab) plus -> (ab,c,m) plus ->
  142. (b,c,bc) plus -> (a,bc,n) plus -> (m,n) equal = fun p1 p2 p3 p4 ->
  143. match p1, p4 with
  144. | PlusZ b, PlusZ bc ->
  145. let Eq = plus_func p2 p3 in Eq
  146. | PlusS p1', PlusS p4' ->
  147. let PlusS p2' = p2 in
  148. let Eq = plus_assoc p1' p2' p3 p4' in Eq
  149. ;;
  150. (* 3.9 Computing Programs and Properties Simultaneously *)
  151. (* Plus and app1 are moved to section 2 *)
  152. let smaller : type a b. (a succ, b succ) le -> (a,b) le =
  153. function LeS x -> x ;;
  154. type (_,_) diff = Diff : 'c nat * ('a,'c,'b) plus -> ('a,'b) diff ;;
  155. (*
  156. let rec diff : type a b. (a,b) le -> a nat -> b nat -> (a,b) diff =
  157. fun le a b ->
  158. match a, b, le with
  159. | NZ, m, _ -> Diff (m, PlusZ m)
  160. | NS x, NZ, _ -> assert false
  161. | NS x, NS y, q ->
  162. match diff (smaller q) x y with Diff (m, p) -> Diff (m, PlusS p)
  163. ;;
  164. *)
  165. let rec diff : type a b. (a,b) le -> a nat -> b nat -> (a,b) diff =
  166. fun le a b ->
  167. match le, a, b with
  168. | LeZ _, _, m -> Diff (m, PlusZ m)
  169. | LeS q, NS x, NS y ->
  170. match diff q x y with Diff (m, p) -> Diff (m, PlusS p)
  171. ;;
  172. let rec diff : type a b. (a,b) le -> a nat -> b nat -> (a,b) diff =
  173. fun le a b ->
  174. match a, b,le with (* warning *)
  175. | NZ, m, LeZ _ -> Diff (m, PlusZ m)
  176. | NS x, NS y, LeS q ->
  177. match diff q x y with Diff (m, p) -> Diff (m, PlusS p)
  178. ;;
  179. let rec diff : type a b. (a,b) le -> b nat -> (a,b) diff =
  180. fun le b ->
  181. match b,le with
  182. | m, LeZ _ -> Diff (m, PlusZ m)
  183. | NS y, LeS q ->
  184. match diff q y with Diff (m, p) -> Diff (m, PlusS p)
  185. ;;
  186. type (_,_) filter = Filter : ('m,'n) le * ('a,'m) seq -> ('a,'n) filter
  187. let rec leS' : type m n. (m,n) le -> (m,n succ) le = function
  188. | LeZ n -> LeZ (NS n)
  189. | LeS le -> LeS (leS' le)
  190. ;;
  191. let rec filter : type a n. (a -> bool) -> (a,n) seq -> (a,n) filter =
  192. fun f s ->
  193. match s with
  194. | Snil -> Filter (LeZ NZ, Snil)
  195. | Scons (a,l) ->
  196. match filter f l with Filter (le, l') ->
  197. if f a then Filter (LeS le, Scons (a, l'))
  198. else Filter (leS' le, l')
  199. ;;
  200. (* 4.1 AVL trees *)
  201. type (_,_,_) balance =
  202. | Less : ('h, 'h succ, 'h succ) balance
  203. | Same : ('h, 'h, 'h) balance
  204. | More : ('h succ, 'h, 'h succ) balance
  205. type _ avl =
  206. | Leaf : zero avl
  207. | Node :
  208. ('hL, 'hR, 'hMax) balance * 'hL avl * int * 'hR avl -> 'hMax succ avl
  209. type avl' = Avl : 'h avl -> avl'
  210. ;;
  211. let empty = Avl Leaf
  212. let rec elem : type h. int -> h avl -> bool = fun x t ->
  213. match t with
  214. | Leaf -> false
  215. | Node (_, l, y, r) ->
  216. x = y || if x < y then elem x l else elem x r
  217. ;;
  218. let rec rotr : type n. (n succ succ) avl -> int -> n avl ->
  219. ((n succ succ) avl, (n succ succ succ) avl) sum =
  220. fun tL y tR ->
  221. match tL with
  222. | Node (Same, a, x, b) -> Inr (Node (Less, a, x, Node (More, b, y, tR)))
  223. | Node (More, a, x, b) -> Inl (Node (Same, a, x, Node (Same, b, y, tR)))
  224. | Node (Less, a, x, Node (Same, b, z, c)) ->
  225. Inl (Node (Same, Node (Same, a, x, b), z, Node (Same, c, y, tR)))
  226. | Node (Less, a, x, Node (Less, b, z, c)) ->
  227. Inl (Node (Same, Node (More, a, x, b), z, Node (Same, c, y, tR)))
  228. | Node (Less, a, x, Node (More, b, z, c)) ->
  229. Inl (Node (Same, Node (Same, a, x, b), z, Node (Less, c, y, tR)))
  230. ;;
  231. let rec rotl : type n. n avl -> int -> (n succ succ) avl ->
  232. ((n succ succ) avl, (n succ succ succ) avl) sum =
  233. fun tL u tR ->
  234. match tR with
  235. | Node (Same, a, x, b) -> Inr (Node (More, Node (Less, tL, u, a), x, b))
  236. | Node (Less, a, x, b) -> Inl (Node (Same, Node (Same, tL, u, a), x, b))
  237. | Node (More, Node (Same, a, x, b), y, c) ->
  238. Inl (Node (Same, Node (Same, tL, u, a), x, Node (Same, b, y, c)))
  239. | Node (More, Node (Less, a, x, b), y, c) ->
  240. Inl (Node (Same, Node (More, tL, u, a), x, Node (Same, b, y, c)))
  241. | Node (More, Node (More, a, x, b), y, c) ->
  242. Inl (Node (Same, Node (Same, tL, u, a), x, Node (Less, b, y, c)))
  243. ;;
  244. let rec ins : type n. int -> n avl -> (n avl, (n succ) avl) sum =
  245. fun x t ->
  246. match t with
  247. | Leaf -> Inr (Node (Same, Leaf, x, Leaf))
  248. | Node (bal, a, y, b) ->
  249. if x = y then Inl t else
  250. if x < y then begin
  251. match ins x a with
  252. | Inl a -> Inl (Node (bal, a, y, b))
  253. | Inr a ->
  254. match bal with
  255. | Less -> Inl (Node (Same, a, y, b))
  256. | Same -> Inr (Node (More, a, y, b))
  257. | More -> rotr a y b
  258. end else begin
  259. match ins x b with
  260. | Inl b -> Inl (Node (bal, a, y, b) : n avl)
  261. | Inr b ->
  262. match bal with
  263. | More -> Inl (Node (Same, a, y, b) : n avl)
  264. | Same -> Inr (Node (Less, a, y, b) : n succ avl)
  265. | Less -> rotl a y b
  266. end
  267. ;;
  268. let insert x (Avl t) =
  269. match ins x t with
  270. | Inl t -> Avl t
  271. | Inr t -> Avl t
  272. ;;
  273. let rec del_min : type n. (n succ) avl -> int * (n avl, (n succ) avl) sum =
  274. function
  275. | Node (Less, Leaf, x, r) -> (x, Inl r)
  276. | Node (Same, Leaf, x, r) -> (x, Inl r)
  277. | Node (bal, (Node _ as l) , x, r) ->
  278. match del_min l with
  279. | y, Inr l -> (y, Inr (Node (bal, l, x, r)))
  280. | y, Inl l ->
  281. (y, match bal with
  282. | Same -> Inr (Node (Less, l, x, r))
  283. | More -> Inl (Node (Same, l, x, r))
  284. | Less -> rotl l x r)
  285. type _ avl_del =
  286. | Dsame : 'n avl -> 'n avl_del
  287. | Ddecr : ('m succ, 'n) equal * 'm avl -> 'n avl_del
  288. let rec del : type n. int -> n avl -> n avl_del = fun y t ->
  289. match t with
  290. | Leaf -> Dsame Leaf
  291. | Node (bal, l, x, r) ->
  292. if x = y then begin
  293. match r with
  294. | Leaf ->
  295. begin match bal with
  296. | Same -> Ddecr (Eq, l)
  297. | More -> Ddecr (Eq, l)
  298. end
  299. | Node _ ->
  300. begin match bal, del_min r with
  301. | _, (z, Inr r) -> Dsame (Node (bal, l, z, r))
  302. | Same, (z, Inl r) -> Dsame (Node (More, l, z, r))
  303. | Less, (z, Inl r) -> Ddecr (Eq, Node (Same, l, z, r))
  304. | More, (z, Inl r) ->
  305. match rotr l z r with
  306. | Inl t -> Ddecr (Eq, t)
  307. | Inr t -> Dsame t
  308. end
  309. end else if y < x then begin
  310. match del y l with
  311. | Dsame l -> Dsame (Node (bal, l, x, r))
  312. | Ddecr(Eq,l) ->
  313. begin match bal with
  314. | Same -> Dsame (Node (Less, l, x, r))
  315. | More -> Ddecr (Eq, Node (Same, l, x, r))
  316. | Less ->
  317. match rotl l x r with
  318. | Inl t -> Ddecr (Eq, t)
  319. | Inr t -> Dsame t
  320. end
  321. end else begin
  322. match del y r with
  323. | Dsame r -> Dsame (Node (bal, l, x, r))
  324. | Ddecr(Eq,r) ->
  325. begin match bal with
  326. | Same -> Dsame (Node (More, l, x, r))
  327. | Less -> Ddecr (Eq, Node (Same, l, x, r))
  328. | More ->
  329. match rotr l x r with
  330. | Inl t -> Ddecr (Eq, t)
  331. | Inr t -> Dsame t
  332. end
  333. end
  334. ;;
  335. let delete x (Avl t) =
  336. match del x t with
  337. | Dsame t -> Avl t
  338. | Ddecr (_, t) -> Avl t
  339. ;;
  340. (* Exercise 22: Red-black trees *)
  341. type red
  342. type black
  343. type (_,_) sub_tree =
  344. | Bleaf : (black, zero) sub_tree
  345. | Rnode :
  346. (black, 'n) sub_tree * int * (black, 'n) sub_tree -> (red, 'n) sub_tree
  347. | Bnode :
  348. ('cL, 'n) sub_tree * int * ('cR, 'n) sub_tree -> (black, 'n succ) sub_tree
  349. type rb_tree = Root : (black, 'n) sub_tree -> rb_tree
  350. ;;
  351. type dir = LeftD | RightD
  352. type (_,_) ctxt =
  353. | CNil : (black,'n) ctxt
  354. | CRed : int * dir * (black,'n) sub_tree * (red,'n) ctxt -> (black,'n) ctxt
  355. | CBlk : int * dir * ('c1,'n) sub_tree * (black, 'n succ) ctxt -> ('c,'n) ctxt
  356. ;;
  357. let blacken = function
  358. Rnode (l, e, r) -> Bnode (l, e, r)
  359. type _ crep =
  360. | Red : red crep
  361. | Black : black crep
  362. let color : type c n. (c,n) sub_tree -> c crep = function
  363. | Bleaf -> Black
  364. | Rnode _ -> Red
  365. | Bnode _ -> Black
  366. ;;
  367. let rec fill : type c n. (c,n) ctxt -> (c,n) sub_tree -> rb_tree =
  368. fun ct t ->
  369. match ct with
  370. | CNil -> Root t
  371. | CRed (e, LeftD, uncle, c) -> fill c (Rnode (uncle, e, t))
  372. | CRed (e, RightD, uncle, c) -> fill c (Rnode (t, e, uncle))
  373. | CBlk (e, LeftD, uncle, c) -> fill c (Bnode (uncle, e, t))
  374. | CBlk (e, RightD, uncle, c) -> fill c (Bnode (t, e, uncle))
  375. ;;
  376. let recolor d1 pE sib d2 gE uncle t =
  377. match d1, d2 with
  378. | LeftD, RightD -> Rnode (Bnode (sib, pE, t), gE, uncle)
  379. | RightD, RightD -> Rnode (Bnode (t, pE, sib), gE, uncle)
  380. | LeftD, LeftD -> Rnode (uncle, gE, Bnode (sib, pE, t))
  381. | RightD, LeftD -> Rnode (uncle, gE, Bnode (t, pE, sib))
  382. ;;
  383. let rotate d1 pE sib d2 gE uncle (Rnode (x, e, y)) =
  384. match d1, d2 with
  385. | RightD, RightD -> Bnode (Rnode (x,e,y), pE, Rnode (sib, gE, uncle))
  386. | LeftD, RightD -> Bnode (Rnode (sib, pE, x), e, Rnode (y, gE, uncle))
  387. | LeftD, LeftD -> Bnode (Rnode (uncle, gE, sib), pE, Rnode (x,e,y))
  388. | RightD, LeftD -> Bnode (Rnode (uncle, gE, x), e, Rnode (y, pE, sib))
  389. ;;
  390. let rec repair : type c n. (red,n) sub_tree -> (c,n) ctxt -> rb_tree =
  391. fun t ct ->
  392. match ct with
  393. | CNil -> Root (blacken t)
  394. | CBlk (e, LeftD, sib, c) -> fill c (Bnode (sib, e, t))
  395. | CBlk (e, RightD, sib, c) -> fill c (Bnode (t, e, sib))
  396. | CRed (e, dir, sib, CBlk (e', dir', uncle, ct)) ->
  397. match color uncle with
  398. | Red -> repair (recolor dir e sib dir' e' (blacken uncle) t) ct
  399. | Black -> fill ct (rotate dir e sib dir' e' uncle t)
  400. ;;
  401. let rec ins : type c n. int -> (c,n) sub_tree -> (c,n) ctxt -> rb_tree =
  402. fun e t ct ->
  403. match t with
  404. | Rnode (l, e', r) ->
  405. if e < e' then ins e l (CRed (e', RightD, r, ct))
  406. else ins e r (CRed (e', LeftD, l, ct))
  407. | Bnode (l, e', r) ->
  408. if e < e' then ins e l (CBlk (e', RightD, r, ct))
  409. else ins e r (CBlk (e', LeftD, l, ct))
  410. | Bleaf -> repair (Rnode (Bleaf, e, Bleaf)) ct
  411. ;;
  412. let insert e (Root t) = ins e t CNil
  413. ;;
  414. (* 5.7 typed object languages using GADTs *)
  415. type _ term =
  416. | Const : int -> int term
  417. | Add : (int * int -> int) term
  418. | LT : (int * int -> bool) term
  419. | Ap : ('a -> 'b) term * 'a term -> 'b term
  420. | Pair : 'a term * 'b term -> ('a * 'b) term
  421. let ex1 = Ap (Add, Pair (Const 3, Const 5))
  422. let ex2 = Pair (ex1, Const 1)
  423. let rec eval_term : type a. a term -> a = function
  424. | Const x -> x
  425. | Add -> fun (x,y) -> x+y
  426. | LT -> fun (x,y) -> x<y
  427. | Ap(f,x) -> eval_term f (eval_term x)
  428. | Pair(x,y) -> (eval_term x, eval_term y)
  429. type _ rep =
  430. | Rint : int rep
  431. | Rbool : bool rep
  432. | Rpair : 'a rep * 'b rep -> ('a * 'b) rep
  433. | Rfun : 'a rep * 'b rep -> ('a -> 'b) rep
  434. type (_,_) equal = Eq : ('a,'a) equal
  435. let rec rep_equal : type a b. a rep -> b rep -> (a, b) equal option =
  436. fun ra rb ->
  437. match ra, rb with
  438. | Rint, Rint -> Some Eq
  439. | Rbool, Rbool -> Some Eq
  440. | Rpair (a1, a2), Rpair (b1, b2) ->
  441. begin match rep_equal a1 b1 with
  442. | None -> None
  443. | Some Eq -> match rep_equal a2 b2 with
  444. | None -> None
  445. | Some Eq -> Some Eq
  446. end
  447. | Rfun (a1, a2), Rfun (b1, b2) ->
  448. begin match rep_equal a1 b1 with
  449. | None -> None
  450. | Some Eq -> match rep_equal a2 b2 with
  451. | None -> None
  452. | Some Eq -> Some Eq
  453. end
  454. | _ -> None
  455. ;;
  456. type assoc = Assoc : string * 'a rep * 'a -> assoc
  457. let rec assoc : type a. string -> a rep -> assoc list -> a =
  458. fun x r -> function
  459. | [] -> raise Not_found
  460. | Assoc (x', r', v) :: env ->
  461. if x = x' then
  462. match rep_equal r r' with
  463. | None -> failwith ("Wrong type for " ^ x)
  464. | Some Eq -> v
  465. else assoc x r env
  466. type _ term =
  467. | Var : string * 'a rep -> 'a term
  468. | Abs : string * 'a rep * 'b term -> ('a -> 'b) term
  469. | Const : int -> int term
  470. | Add : (int * int -> int) term
  471. | LT : (int * int -> bool) term
  472. | Ap : ('a -> 'b) term * 'a term -> 'b term
  473. | Pair : 'a term * 'b term -> ('a * 'b) term
  474. let rec eval_term : type a. assoc list -> a term -> a =
  475. fun env -> function
  476. | Var (x, r) -> assoc x r env
  477. | Abs (x, r, e) -> fun v -> eval_term (Assoc (x, r, v) :: env) e
  478. | Const x -> x
  479. | Add -> fun (x,y) -> x+y
  480. | LT -> fun (x,y) -> x<y
  481. | Ap(f,x) -> eval_term env f (eval_term env x)
  482. | Pair(x,y) -> (eval_term env x, eval_term env y)
  483. ;;
  484. let ex3 = Abs ("x", Rint, Ap (Add, Pair (Var("x",Rint), Var("x",Rint))))
  485. let ex4 = Ap (ex3, Const 3)
  486. let v4 = eval_term [] ex4
  487. ;;
  488. (* 5.9/5.10 Language with binding *)
  489. type rnil
  490. type (_,_,_) rcons
  491. type _ is_row =
  492. | Rnil : rnil is_row
  493. | Rcons : 'c is_row -> ('a,'b,'c) rcons is_row
  494. type (_,_) lam =
  495. | Const : int -> ('e, int) lam
  496. | Var : 'a -> (('a,'t,'e) rcons, 't) lam
  497. | Shift : ('e,'t) lam -> (('a,'q,'e) rcons, 't) lam
  498. | Abs : 'a * (('a,'s,'e) rcons, 't) lam -> ('e, 's -> 't) lam
  499. | App : ('e, 's -> 't) lam * ('e, 's) lam -> ('e, 't) lam
  500. type x = X
  501. type y = Y
  502. let ex1 = App (Var X, Shift (Var Y))
  503. let ex2 = Abs (X, Abs (Y, App (Shift (Var X), Var Y)))
  504. ;;
  505. type _ env =
  506. | Enil : rnil env
  507. | Econs : 'a * 't * 'e env -> ('a, 't, 'e) rcons env
  508. let rec eval_lam : type e t. e env -> (e, t) lam -> t =
  509. fun env m ->
  510. match env, m with
  511. | _, Const n -> n
  512. | Econs (_, v, r), Var _ -> v
  513. | Econs (_, _, r), Shift e -> eval_lam r e
  514. | _, Abs (n, body) -> fun x -> eval_lam (Econs (n, x, env)) body
  515. | _, App (f, x) -> eval_lam env f (eval_lam env x)
  516. ;;
  517. type add = Add
  518. type suc = Suc
  519. let env0 = Econs (Zero, 0, Econs (Suc, succ, Econs (Add, (+), Enil)))
  520. let _0 : (_, int) lam = Var Zero
  521. let suc x = App (Shift (Var Suc : (_, int -> int) lam), x)
  522. let _1 = suc _0
  523. let _2 = suc _1
  524. let _3 = suc _2
  525. let add = Shift (Shift (Var Add : (_, int -> int -> int) lam))
  526. let double = Abs (X, App (App (Shift add, Var X), Var X))
  527. let ex3 = App (double, _3)
  528. ;;
  529. let v3 = eval_lam env0 ex3
  530. ;;
  531. (* 5.13: Constructing typing derivations at runtime *)
  532. (* Modified slightly to use the language of 5.10, since this is more fun.
  533. Of course this works also with the language of 5.12. *)
  534. type _ rep =
  535. | I : int rep
  536. | Ar : 'a rep * 'b rep -> ('a -> 'b) rep
  537. let rec compare : type a b. a rep -> b rep -> (string, (a,b) equal) sum =
  538. fun a b ->
  539. match a, b with
  540. | I, I -> Inr Eq
  541. | Ar(x,y), Ar(s,t) ->
  542. begin match compare x s with
  543. | Inl _ as e -> e
  544. | Inr Eq -> match compare y t with
  545. | Inl _ as e -> e
  546. | Inr Eq as e -> e
  547. end
  548. | I, Ar _ -> Inl "I <> Ar _"
  549. | Ar _, I -> Inl "Ar _ <> I"
  550. ;;
  551. type term =
  552. | C of int
  553. | Ab : string * 'a rep * term -> term
  554. | Ap of term * term
  555. | V of string
  556. type _ ctx =
  557. | Cnil : rnil ctx
  558. | Ccons : 't * string * 'x rep * 'e ctx -> ('t,'x,'e) rcons ctx
  559. ;;
  560. type _ checked =
  561. | Cerror of string
  562. | Cok : ('e,'t) lam * 't rep -> 'e checked
  563. let rec lookup : type e. string -> e ctx -> e checked =
  564. fun name ctx ->
  565. match ctx with
  566. | Cnil -> Cerror ("Name not found: " ^ name)
  567. | Ccons (l,s,t,rs) ->
  568. if s = name then Cok (Var l,t) else
  569. match lookup name rs with
  570. | Cerror m -> Cerror m
  571. | Cok (v, t) -> Cok (Shift v, t)
  572. ;;
  573. let rec tc : type n e. n nat -> e ctx -> term -> e checked =
  574. fun n ctx t ->
  575. match t with
  576. | V s -> lookup s ctx
  577. | Ap(f,x) ->
  578. begin match tc n ctx f with
  579. | Cerror _ as e -> e
  580. | Cok (f', ft) -> match tc n ctx x with
  581. | Cerror _ as e -> e
  582. | Cok (x', xt) ->
  583. match ft with
  584. | Ar (a, b) ->
  585. begin match compare a xt with
  586. | Inl s -> Cerror s
  587. | Inr Eq -> Cok (App (f',x'), b)
  588. end
  589. | _ -> Cerror "Non fun in Ap"
  590. end
  591. | Ab(s,t,body) ->
  592. begin match tc (NS n) (Ccons (n, s, t, ctx)) body with
  593. | Cerror _ as e -> e
  594. | Cok (body', et) -> Cok (Abs (n, body'), Ar (t, et))
  595. end
  596. | C m -> Cok (Const m, I)
  597. ;;
  598. let ctx0 =
  599. Ccons (Zero, "0", I,
  600. Ccons (Suc, "S", Ar(I,I),
  601. Ccons (Add, "+", Ar(I,Ar(I,I)), Cnil)))
  602. let ex1 = Ab ("x", I, Ap(Ap(V"+",V"x"),V"x"));;
  603. let c1 = tc NZ ctx0 ex1;;
  604. let ex2 = Ap (ex1, C 3);;
  605. let c2 = tc NZ ctx0 ex2;;
  606. let eval_checked env = function
  607. | Cerror s -> failwith s
  608. | Cok (e, I) -> (eval_lam env e : int)
  609. | Cok _ -> failwith "Can only evaluate expressions of type I"
  610. ;;
  611. let v2 = eval_checked env0 c2 ;;
  612. (* 5.12 Soundness *)
  613. type pexp
  614. type pval
  615. type _ mode =
  616. | Pexp : pexp mode
  617. | Pval : pval mode
  618. type (_,_) tarr
  619. type tint
  620. type (_,_) rel =
  621. | IntR : (tint, int) rel
  622. | IntTo : ('b, 's) rel -> ((tint, 'b) tarr, int -> 's) rel
  623. type (_,_,_) lam =
  624. | Const : ('a,'b) rel * 'b -> (pval, 'env, 'a) lam
  625. | Var : 'a -> (pval, ('a,'t,'e) rcons, 't) lam
  626. | Shift : ('m,'e,'t) lam -> ('m, ('a,'q,'e) rcons, 't) lam
  627. | Lam : 'a * ('m, ('a,'s,'e) rcons, 't) lam -> (pval, 'e, ('s,'t) tarr) lam
  628. | App : ('m1, 'e, ('s,'t) tarr) lam * ('m2, 'e, 's) lam -> (pexp, 'e, 't) lam
  629. ;;
  630. let ex1 = App (Lam (X, Var X), Const (IntR, 3))
  631. let rec mode : type m e t. (m,e,t) lam -> m mode = function
  632. | Lam (v, body) -> Pval
  633. | Var v -> Pval
  634. | Const (r, v) -> Pval
  635. | Shift e -> mode e
  636. | App _ -> Pexp
  637. ;;
  638. type (_,_) sub =
  639. | Id : ('r,'r) sub
  640. | Bind : 't * ('m,'r2,'x) lam * ('r,'r2) sub -> (('t,'x,'r) rcons, 'r2) sub
  641. | Push : ('r1,'r2) sub -> (('a,'b,'r1) rcons, ('a,'b,'r2) rcons) sub
  642. type (_,_) lam' = Ex : ('m, 's, 't) lam -> ('s,'t) lam'
  643. ;;
  644. let rec subst : type m1 r t s. (m1,r,t) lam -> (r,s) sub -> (s,t) lam' =
  645. fun t s ->
  646. match t, s with
  647. | _, Id -> Ex t
  648. | Const(r,c), sub -> Ex (Const (r,c))
  649. | Var v, Bind (x, e, r) -> Ex e
  650. | Var v, Push sub -> Ex (Var v)
  651. | Shift e, Bind (_, _, r) -> subst e r
  652. | Shift e, Push sub ->
  653. (match subst e sub with Ex a -> Ex (Shift a))
  654. | App(f,x), sub ->
  655. (match subst f sub, subst x sub with Ex g, Ex y -> Ex (App (g,y)))
  656. | Lam(v,x), sub ->
  657. (match subst x (Push sub) with Ex body -> Ex (Lam (v, body)))
  658. ;;
  659. type closed = rnil
  660. type 'a rlam = ((pexp,closed,'a) lam, (pval,closed,'a) lam) sum ;;
  661. let rec rule : type a b.
  662. (pval, closed, (a,b) tarr) lam -> (pval, closed, a) lam -> b rlam =
  663. fun v1 v2 ->
  664. match v1, v2 with
  665. | Lam(x,body), v ->
  666. begin
  667. match subst body (Bind (x, v, Id)) with Ex term ->
  668. match mode term with
  669. | Pexp -> Inl term
  670. | Pval -> Inr term
  671. end
  672. | Const (IntTo b, f), Const (IntR, x) ->
  673. Inr (Const (b, f x))
  674. ;;
  675. let rec onestep : type m t. (m,closed,t) lam -> t rlam = function
  676. | Lam (v, body) -> Inr (Lam (v, body))
  677. | Const (r, v) -> Inr (Const (r, v))
  678. | App (e1, e2) ->
  679. match mode e1, mode e2 with
  680. | Pexp, _->
  681. begin match onestep e1 with
  682. | Inl e -> Inl(App(e,e2))
  683. | Inr v -> Inl(App(v,e2))
  684. end
  685. | Pval, Pexp ->
  686. begin match onestep e2 with
  687. | Inl e -> Inl(App(e1,e))
  688. | Inr v -> Inl(App(e1,v))
  689. end
  690. | Pval, Pval -> rule e1 e2
  691. ;;