%%% Constraint-Based Type Inference %%% Simply-typed fragment % Simple types tp : type. %name tp T a. => : tp -> tp -> tp. %infix right 8 =>. % Propositions of unification logic (constraints) prop : type. %name prop C. == : tp -> tp -> prop. & : prop -> prop -> prop. tt : prop. exists : (tp -> prop) -> prop. %infix none 10 ==. %infix right 9 &. % Truth of propositions true : prop -> type. %name true P. %mode true *C. ==I : true (T == T). &I : true (C1 & C2) <- true C1 <- true C2. ttI : true tt. existsI : {T:tp} true (exists C) <- true (C T). % Expressions exp : type. %name exp E x. lam : (exp -> exp) -> exp. app : exp -> exp -> exp. % Extrinsic typing judgment of : exp -> tp -> type. %name of D. %mode of +E *T. of_lam : of (lam E) (T1 => T2) <- ({x:exp} of x T1 -> of (E x) T2). of_app : of (app E1 E2) T1 <- of E1 (T2 => T1) <- of E2 T2. %terminates E (of E _). % %covers of +E *T. % Constraint generation con : exp -> tp -> prop -> type. %name con N. %mode con +E +T -C. con_lam : con (lam E) T (exists [a1] exists [a2] C a1 a2 & T == (a1 => a2)) <- ({x:exp} {a1:tp} ({T':tp} con x T' (a1 == T')) -> {a2:tp} con (E x) a2 (C a1 a2)). con_app : con (app E1 E2) T (exists [a2] C1 a2 & C2 a2) <- ({a2:tp} con E1 (a2 => T) (C1 a2)) <- ({a2:tp} con E2 a2 (C2 a2)). %terminates E (con E T _). % Top-level interface con' : exp -> prop -> type. %name con' N'. %mode con' +E -C. con'0 : con' E (exists [a] C a) <- ({a:tp} con E a (C a)). % %world ( pi {x:exp} {a:tp} {n:{T':tp} con x T' (a == T')} % | pi {a:tp} ) % (con E T C). % %covers con +E +T -C. % %total E (con E T _). % Soundness of constraint-based type inference sound : con E T C -> true C -> of E T -> type. %mode sound +N +P -D. sound_lam : sound (con_lam N) (existsI T1 (existsI T2 (&I (==I) P))) (of_lam D) <- ({x:exp} {u:of x T1} {n:{T':tp} con x T' (T1 == T')} sound (n T1) (==I) u % T' = T1 by inversion on ==I? -> sound (N x T1 n T2) P (D x u)). sound_app : sound (con_app N2 N1) (existsI T2 (&I P2 P1)) (of_app D2 D1) <- sound (N1 T2) P1 D1 <- sound (N2 T2) P2 D2. %terminates N (sound N P _). % %world (some {T1:tp} % pi {x:exp} {u:of x T1} {n:{T':tp} con x T' (T1 == T')} % {s:sound (n T1) (==I) u}) % (sound N P D). % %covers sound +N +P -D. % %total N (sound N P _). % Completeness of constraint-based type inference % This is actually the same as soundness with argument reversed complete : con E T C -> of E T -> true C -> type. %mode complete +N +D -P. complete_lam : complete (con_lam N) (of_lam D : of (lam E) (T1 => T2)) (existsI T1 (existsI T2 (&I (==I) P))) <- ({x:exp} {u:of x T1} {n:{T':tp} con x T' (T1 == T')} complete (n T1) u (==I) -> complete (N x T1 n T2) (D x u) P). complete_app : complete (con_app N2 N1) (of_app D2 (D1 : of E1 (T2 => T))) (existsI T2 (&I P2 P1)) <- complete (N1 T2) D1 P1 <- complete (N2 T2) D2 P2. %terminates N (complete N D _). % %covers complete +N +D -P. % %total N (complete N D _).