theory Type_Inference_Template imports Types begin text {* Make the typing relation executable: *} code_pred ctyping . text {* Auxiliary function to collect variables in expressions and commands. The function @{const List.insert} adds an element to a list if it is not already in the list. *} fun avars :: "aexp \ name list \ name list" where "avars (V x) vs = List.insert x vs" | "avars (Plus e1 e2) vs = avars e2 (avars e1 vs)" | "avars _ vs = vs" fun bvars :: "bexp \ name list \ name list" where "bvars (B _) vs = vs" | "bvars (Not e) vs = bvars e vs" | "bvars (And e1 e2) vs = bvars e2 (bvars e1 vs)" | "bvars (Less e1 e2) vs = avars e2 (avars e1 vs)" fun cvars :: "com \ name list \ name list" where "cvars SKIP vs = vs" | "cvars (x ::= a) vs = List.insert x (avars a vs)" | "cvars (c1 ; c2) vs = cvars c2 (cvars c1 vs)" | "cvars (IF b THEN c1 ELSE c2) vs = cvars c2 (cvars c1 (bvars b vs))" | "cvars (WHILE b DO c) vs = cvars c (bvars b vs)" text {* Type variables and constraints *} datatype tvar = TVar name | Type ty fun type_of :: "tyenv \ tvar \ ty" where "type_of \ (TVar v) = \(v)" | "type_of \ (Type t) = t" types constraint = "tvar * tvar" constraints = "constraint list" fun constraint_holds :: "tyenv \ constraint \ bool" (infix "\" 50) where "\ \ (v, v') \ type_of \ v = type_of \ v'" subsection {* Constraint generation *} fun ccollect :: "com \ constraints" where "ccollect _ = []" (* add definition here *) lemma ccollect_sound_and_complete: "\ \ c \ (\C \ set (ccollect c). \ \ C)" (* quickcheck[iterations=200,size=8,report] *) oops subsection {* Constraint solving *} fun solve :: "constraints \ (name * tvar) list \ (name * tvar) list option" where "solve _ M = Some M" (* add real definition here *) subsection {* Type inference *} fun type_infer :: "com \ (name * tvar) list option" where "type_infer c = (let constraints = ccollect c; vars = cvars c []; init = map (\x. (x, TVar x)) vars in solve constraints init)" subsection {* Specification of type inference *} definition instantiate :: "(name \ ty) \ (name \ tvar) list \ tyenv" where "instantiate I M = (\x. case map_of M x of None \ I x | Some (Type T) \ T | Some (TVar y) \ I y)" fun is_instance :: "tyenv \ (name \ tvar) list \ bool" (infix "<:" 50) where "\ <: [] \ True" | "\ <: ((x,Type t)#M) \ (\(x) = t \ \ <: M)" | "\ <: ((x,TVar y)#M) \ (\(x) = \(y) \ \ <: M)" text {* The following lemmas are formulated in a way that is suitable for counterexample generation with quickcheck. *} lemma type_infer_sound: "(case type_infer c of None \ True | Some M \ (instantiate I M \ c))" (*quickcheck[iterations=200,size=8,report]*) oops lemma type_infer_complete: "\ \ c \ (case type_infer c of None \ False | Some M \ \ <: M)" (*quickcheck[iterations=200,size=8,report]*) oops end