@@ -51,6 +51,7 @@ and exp' =
5151 | UnwrapE of var * typ
5252 | UnrollE of var * typ
5353 | RecE of var * typ * exp
54+ | AnnotE of exp * typ
5455
5556and bind = (bind', unit ) phrase
5657and bind' =
@@ -195,9 +196,7 @@ let unrollE(e, t) =
195196 let x' = var " @" in
196197 letE(VarB (x'@@ e.at, e)@@ e.at, UnrollE (x'@@ e.at, t)@@ span[e.at; t.at])
197198
198- let annotE(e, t) =
199- let x' = var " annot" in
200- appE(FunE (x'@@ t.at, t, VarE (x'@@ t.at)@@ t.at, Expl @@ t.at)@@ span[e.at; t.at], e)
199+ let annotE(e, t) = AnnotE (e, t)
201200
202201let sealE(e, t) =
203202 (* TODO: clone t! *)
@@ -316,6 +315,65 @@ let rollP(p, t2) =
316315 TypE (t1.it@@ p.at)@@ p.at)@@ p.at)@@ p.at)@@ span[p.at; t2.at])
317316
318317
318+ (* Substitution *)
319+
320+ type 'a subst = (string * 'a ) list
321+
322+ let subst_exp_var (s : 'a subst ) (v : var ) = try List. assoc v.it s with Not_found -> VarE (v)
323+
324+ let rec subst_exp_typ s t =
325+ (match t.it with
326+ | PathT (e ) -> PathT (subst_exp_exp s e)
327+ | PrimT (s ) -> PrimT (s)
328+ | TypT -> TypT
329+ | HoleT -> HoleT
330+ | StrT (d ) -> StrT (subst_exp_dec s d)
331+ | FunT (v , td , tr , e , i ) ->
332+ FunT (v, subst_exp_typ s td, subst_exp_typ ((v.it, VarE (v))::s) tr, e, i)
333+ | WrapT (t ) -> WrapT (subst_exp_typ s t)
334+ | EqT (e ) -> EqT (subst_exp_exp s e)
335+ | AsT (tl , tr ) -> AsT (subst_exp_typ s tl, subst_exp_typ s tr)
336+ | WithT (t , vs , e ) -> WithT (subst_exp_typ s t, vs, subst_exp_exp s e)
337+ )@@ t.at
338+
339+ and subst_exp_dec s d =
340+ (match d.it with
341+ | EmptyD -> EmptyD
342+ | SeqD (dl , dr ) -> SeqD (subst_exp_dec s dl, subst_exp_dec s dr)
343+ | VarD (v , t ) -> VarD (v, subst_exp_typ s t)
344+ | InclD (t ) -> InclD (subst_exp_typ s t)
345+ )@@ d.at
346+
347+ and subst_exp_exp s e =
348+ (match e.it with
349+ | VarE (v ) -> subst_exp_var s v
350+ | PrimE (s ) -> PrimE (s)
351+ | TypE (t ) -> TypE (subst_exp_typ s t)
352+ | StrE (b ) -> StrE (subst_exp_bind s b)
353+ | FunE (v , t , e , i ) ->
354+ FunE (v, subst_exp_typ s t, subst_exp_exp ((v.it, VarE (v))::s) e, i)
355+ | WrapE (v , t ) -> wrapE(subst_exp_var s v@@ e.at, subst_exp_typ s t)
356+ | RollE (v , t ) -> rollE(subst_exp_var s v@@ e.at, subst_exp_typ s t)
357+ | IfE (v , ec , ea , t ) ->
358+ ifE(subst_exp_var s v@@ e.at, subst_exp_exp s ec, subst_exp_exp s ea, subst_exp_typ s t)
359+ | DotE (e , v ) -> DotE (subst_exp_exp s e, v)
360+ | AppE (vf , va ) -> appE(subst_exp_var s vf@@ e.at, subst_exp_var s va@@ e.at)
361+ | UnwrapE (v , t ) -> unwrapE(subst_exp_var s v@@ e.at, subst_exp_typ s t)
362+ | UnrollE (v , t ) -> unrollE(subst_exp_var s v@@ e.at, subst_exp_typ s t)
363+ | RecE (v , t , e ) -> RecE (v, subst_exp_typ s t, subst_exp_exp ((v.it, VarE (v))::s) e)
364+ | AnnotE (e , t ) -> AnnotE (subst_exp_exp s e, subst_exp_typ s t)
365+ )@@ e.at
366+
367+ and subst_exp_bind s b =
368+ (match b.it with
369+ | EmptyB -> EmptyB
370+ | SeqB (bl , br ) -> SeqB (subst_exp_bind s bl, subst_exp_bind s br)
371+ | VarB (v , e ) -> VarB (v, subst_exp_exp s e)
372+ | InclB (e ) -> InclB (subst_exp_exp s e)
373+ | TypeErrorB (e ) -> TypeErrorB (subst_exp_exp s e)
374+ )@@ b.at
375+
376+
319377(* String conversion *)
320378
321379let node label = function
@@ -367,6 +425,7 @@ let label_of_exp e =
367425 | UnwrapE _ -> " UnwrapE"
368426 | UnrollE _ -> " UnrollE"
369427 | RecE _ -> " RecE"
428+ | AnnotE _ -> " AnnotE"
370429
371430let label_of_bind b =
372431 match b.it with
@@ -425,6 +484,7 @@ and string_of_exp e =
425484 | UnwrapE (x , t ) -> node' [string_of_var x; string_of_typ t]
426485 | UnrollE (x , t ) -> node' [string_of_var x; string_of_typ t]
427486 | RecE (x , t , e ) -> node' [string_of_var x; string_of_typ t; string_of_exp e]
487+ | AnnotE (e , t ) -> node' [string_of_exp e; string_of_typ t]
428488
429489and string_of_bind b =
430490 let node' = node (label_of_bind b) in
@@ -434,3 +494,56 @@ and string_of_bind b =
434494 | VarB (x , e ) -> node' [string_of_var x; string_of_exp e]
435495 | InclB (e ) -> node' [string_of_exp e]
436496 | TypeErrorB (e ) -> node' [string_of_exp e]
497+
498+
499+ (* rec ... and ... *)
500+
501+ let rec extract_sig_exp p e =
502+ let s, d =
503+ match e.it with
504+ | StrE (b ) ->
505+ let s, d = extract_sig_bind p b in
506+ s, StrT (d)
507+ | TypE _ ->
508+ [] , TypT
509+ | FunE (v , td , e , i ) ->
510+ let _, tc = extract_sig_exp p e in
511+ let p =
512+ if i.it == Impl then Pure else
513+ match e.it with
514+ | FunE _ -> Pure
515+ | TypE _ -> Pure
516+ | _ -> Impure in
517+ [] , FunT (v, td, tc, p@@ e.at, i)
518+ | AnnotE (e , t ) ->
519+ [] , t.it
520+ | _ -> [] , HoleT in
521+ s, d@@ e.at
522+
523+ and extract_sig_bind p b =
524+ let s, d =
525+ match b.it with
526+ | EmptyB -> [] , EmptyD
527+ | SeqB (bl , br ) ->
528+ let sl, dl = extract_sig_bind p bl in
529+ let sr, dr = extract_sig_bind p br in
530+ (sl @ sr), SeqD (dl, dr)
531+ | VarB (v , e ) ->
532+ let s, t = extract_sig_exp (DotE (p, v)@@ b.at) e in
533+ ((v.it, DotE (p, v)) :: s), VarD (v, t)
534+ | InclB (e ) ->
535+ let s, t = extract_sig_exp p e in
536+ s, InclD (t)
537+ | TypeErrorB (e ) -> [] , EmptyD in
538+ s, d@@ b.at
539+
540+ let recB(b) =
541+ let r = var " R" in
542+ let s, d = extract_sig_bind (VarE (r@@ b.at)@@ b.at) b in
543+ let b' = subst_exp_bind s b in
544+ let b' = InclB (RecE (r@@ b.at, StrT (d)@@ b.at, StrE (b')@@ b.at)@@ b.at) in
545+ (*
546+ List.iter (fun (v, e) -> Printf.printf "%s %s\n" v (string_of_exp (e@@b.at))) s;
547+ Printf.printf "%s\n" (string_of_bind (b'@@b.at));
548+ *)
549+ b'
0 commit comments