@@ -101,12 +101,31 @@ let unify_typ t1 t2 =
101101 Trace. sub (lazy (" [unify_typ] t2 = " ^ string_of_norm_typ t2));
102102 unify_typ t1 t2
103103
104+ let rec psubst p t =
105+ match p with
106+ | VarT (a , k ) -> a, t
107+ | AppT (p' , ts ) -> psubst p' (LamT (List. map unvarT ts, t))
108+ | _ -> assert false
109+
104110
105111let rec sub_typ env t1 t2 ps =
106112 Trace. sub (lazy (" [sub_typ] t1 = " ^ string_of_norm_typ t1));
107113 Trace. sub (lazy (" [sub_typ] t2 = " ^ string_of_norm_typ t2));
108114 Trace. sub (lazy (" [sub_typ] ps = " ^
109115 String. concat " , " (List. map string_of_norm_typ ps)));
116+ let ts', zs', t2, ps =
117+ if ps <> [] then
118+ let su, zs' = match_typ env t1 t2 ps in
119+ Trace. sub (lazy (" [sub_typ] su = " ^
120+ String. concat " , " (List. map (fun (p , t ) -> Printf. sprintf " [= %s] - [= %s]\n " (string_of_typ p) (string_of_typ t)) su)));
121+ let t2 = subst_typ (List. map (fun (p , t ) -> psubst p t) su) t2 in
122+ let ps' = List. filter (fun p -> List. mem_assoc p su) ps in
123+ let ts' = List. map (fun p -> List. assoc p su) ps' in
124+ let ps = List. filter (fun p -> not (List. mem_assoc p su)) ps in
125+ ts', zs', t2, ps
126+ else
127+ [] , [] , t2, ps
128+ in
110129 let e1 = IL. VarE (" x" ) in
111130 let ts, zs, e =
112131 match norm_typ t1, freshen_typ env (norm_typ t2) with
@@ -267,7 +286,7 @@ let rec sub_typ env t1 t2 ps =
267286 Trace. sub (lazy (" [sub_typ] done ts = " ^
268287 String. concat " , " (List. map string_of_norm_typ ts)));
269288 Trace. sub (lazy (" [sub_typ] done x -> " ^ IL. string_of_exp e));
270- ts, zs, IL. LamE (" x" , erase_typ t1, e)
289+ ts' @ ts, zs' @ zs, IL. LamE (" x" , erase_typ t1, e)
271290
272291and sub_extyp env s1 s2 ps =
273292 Trace. sub (lazy (" [sub_extyp] s1 = " ^ string_of_norm_extyp s1));
@@ -290,18 +309,11 @@ and sub_row env tr1 tr2 ps =
290309 | [] ->
291310 [] , [] , []
292311 | (l , t2 )::tr2' ->
293- Trace. sub (lazy (" [sub_row] l = " ^ l));
294312 let ts1, zs1, f =
295313 try sub_typ env (List. assoc l tr1) t2 ps with
296314 | Not_found -> raise (Sub (Struct (l, Missing )))
297315 | Sub e -> raise (Sub (Struct (l, e)))
298316 in
299- let rec psubst p t =
300- match p with
301- | VarT (a , k ) -> a, t
302- | AppT (p' , ts ) -> psubst p' (LamT (List. map unvarT ts, t))
303- | _ -> assert false
304- in
305317 let su = List. map2 psubst (Lib.List. take (List. length ts1) ps) ts1 in
306318 let ps' = Lib.List. drop (List. length ts1) ps in
307319 let ts2, zs2, fs = sub_row env tr1 (subst_row su tr2') ps' in
@@ -331,3 +343,67 @@ and equal_row env tr1 tr2 ps =
331343 let _, zs2, _ =
332344 try sub_row env tr2 tr1 ps with Sub e -> raise (Sub (Right e)) in
333345 zs1 @ zs2
346+
347+ and match_typ env t1 t2 ps =
348+ Trace. sub (lazy (" [match_typ] t1 = " ^ string_of_norm_typ t1));
349+ Trace. sub (lazy (" [match_typ] t2 = " ^ string_of_norm_typ t2));
350+ Trace. sub (lazy (" [match_typ] ps = " ^
351+ String. concat " , " (List. map string_of_norm_typ ps)));
352+ match norm_typ t1, freshen_typ env (norm_typ t2) with
353+ | t1 , FunT (aks21 , t21 , ExT(aks22 , t22 ), Implicit) ->
354+ assert (aks22 = [] );
355+ let su, zs = match_typ (add_typs aks21 env) t1 t22 ps in
356+ List. map (fun (p , t ) -> (p, LamT (aks21, t))) su, lift env zs
357+
358+ | FunT (aks11 , t11 , ExT(aks12 , t12 ), Implicit), t2 ->
359+ [] , []
360+
361+ | TypT (s1 ), TypT (s2 ) ->
362+ (match s1, s2 with
363+ | ExT (aks1 , t ), ExT ([] , p ) when List. mem p ps ->
364+ if aks1 <> [] || not (! undecidable_flag || is_small_typ t) then
365+ raise (Sub (Mismatch (t1, t2)));
366+ [(p, t)], []
367+ | _ ->
368+ [] , [] )
369+
370+ | StrT (tr1 ), StrT (tr2 ) ->
371+ match_row env tr1 tr2 ps
372+
373+ | FunT (aks1 , t11 , s1 , Explicit p1 ), FunT (aks2 , t21 , s2 , Explicit p2 ) ->
374+ if p1 = Impure && p2 = Pure then raise (Sub (FunEffect (p1, p2)));
375+ let env' = add_typs aks2 env in
376+ let ts1, zs1, f1 =
377+ try sub_typ env' t21 t11 (varTs aks1) with Sub e ->
378+ raise (Sub (FunParam e)) in
379+ let ps' = List. map (fun p -> AppT (p, varTs aks2)) ps in
380+ let su, zs2 =
381+ try match_extyp env' (subst_extyp (subst aks1 ts1) s1) s2 ps'
382+ with Sub e -> raise (Sub (FunResult e)) in
383+ List. map (function (AppT(p , _ ), t ) -> (p, LamT (aks2, t))
384+ | _ -> assert false ) su, lift env (zs1 @ zs2)
385+
386+ | _ ->
387+ [] , []
388+
389+ and match_extyp env s1 s2 ps =
390+ let ExT (aks2, t2) = freshen_extyp env s2 in
391+ let ExT (aks1, t1) = freshen_extyp (add_typs aks2 env) s1 in
392+ match aks1, aks2 with
393+ | [] , [] ->
394+ match_typ env t1 t2 ps
395+ | _ ->
396+ [] , []
397+
398+ and match_row env tr1 tr2 ps =
399+ match tr2 with
400+ | [] ->
401+ [] , []
402+ | (l , t2 )::tr2' ->
403+ let su1, zs1 =
404+ try match_typ env (List. assoc l tr1) t2 ps with
405+ | Not_found -> raise (Sub (Struct (l, Missing )))
406+ | Sub e -> raise (Sub (Struct (l, e)))
407+ in
408+ let su2, zs2 = match_row env tr1 (subst_row (List. map (fun (p , t ) -> psubst p t) su1) tr2') ps in
409+ su1 @ su2, zs1 @ zs2
0 commit comments