102 let |
102 let |
103 |
103 |
104 (* user space type system: only permits 'a type variable, improves towards 'a *) |
104 (* user space type system: only permits 'a type variable, improves towards 'a *) |
105 val algebra = Sign.classes_of thy; |
105 val algebra = Sign.classes_of thy; |
106 val inter_sort = curry (Sorts.inter_sort algebra); |
106 val inter_sort = curry (Sorts.inter_sort algebra); |
107 val proto_base_sort = if null sups then Sign.defaultS thy |
107 val proto_base_sort = |
|
108 if null sups then Sign.defaultS thy |
108 else fold inter_sort (map (Class.base_sort thy) sups) []; |
109 else fold inter_sort (map (Class.base_sort thy) sups) []; |
109 val base_constraints = (map o apsnd) |
110 val base_constraints = (map o apsnd) |
110 (map_type_tfree (K (TVar ((Name.aT, 0), proto_base_sort))) o fst o snd) |
111 (map_type_tfree (K (TVar ((Name.aT, 0), proto_base_sort))) o fst o snd) |
111 (Class.these_operations thy sups); |
112 (Class.these_operations thy sups); |
112 val reject_bcd_etc = (map o map_atyps) (fn T as TFree (v, sort) => |
113 val reject_bcd_etc = (map o map_atyps) (fn T as TFree (v, sort) => |
114 else error ("No type variable other than " ^ Name.aT ^ " allowed in class specification") |
115 else error ("No type variable other than " ^ Name.aT ^ " allowed in class specification") |
115 | T => T); |
116 | T => T); |
116 fun singleton_fixate Ts = |
117 fun singleton_fixate Ts = |
117 let |
118 let |
118 fun extract f = (fold o fold_atyps) f Ts []; |
119 fun extract f = (fold o fold_atyps) f Ts []; |
119 val tfrees = extract |
120 val tfrees = extract (fn TFree (v, sort) => insert (op =) (v, sort) | _ => I); |
120 (fn TFree (v, sort) => insert (op =) (v, sort) | _ => I); |
121 val inferred_sort = extract (fn TVar (_, sort) => inter_sort sort | _ => I); |
121 val inferred_sort = extract |
122 val fixate_sort = |
122 (fn TVar (_, sort) => inter_sort sort | _ => I); |
123 if null tfrees then inferred_sort |
123 val fixate_sort = if null tfrees then inferred_sort |
124 else |
124 else case tfrees |
125 (case tfrees of |
125 of [(_, a_sort)] => if Sorts.sort_le algebra (a_sort, inferred_sort) |
126 [(_, a_sort)] => if Sorts.sort_le algebra (a_sort, inferred_sort) |
126 then inter_sort a_sort inferred_sort |
127 then inter_sort a_sort inferred_sort |
127 else error ("Type inference imposes additional sort constraint " |
128 else error ("Type inference imposes additional sort constraint " |
128 ^ Syntax.string_of_sort_global thy inferred_sort |
129 ^ Syntax.string_of_sort_global thy inferred_sort |
129 ^ " of type parameter " ^ Name.aT ^ " of sort " |
130 ^ " of type parameter " ^ Name.aT ^ " of sort " |
130 ^ Syntax.string_of_sort_global thy a_sort) |
131 ^ Syntax.string_of_sort_global thy a_sort) |
131 | _ => error "Multiple type variables in class specification"; |
132 | _ => error "Multiple type variables in class specification"); |
132 in (map o map_atyps) (K (TFree (Name.aT, fixate_sort))) Ts end; |
133 in (map o map_atyps) (K (TFree (Name.aT, fixate_sort))) Ts end; |
133 fun after_infer_fixate Ts = |
134 fun after_infer_fixate Ts = |
134 let |
135 let |
135 val sort' = (fold o fold_atyps) (fn T as TFree _ => I | T as TVar (vi, sort) => |
136 val sort' = (fold o fold_atyps) (fn T as TFree _ => I | T as TVar (vi, sort) => |
136 if Type_Infer.is_param vi then inter_sort sort else I) Ts []; |
137 if Type_Infer.is_param vi then inter_sort sort else I) Ts []; |
156 | filter_element (e as Element.Fixes _) = SOME e |
157 | filter_element (e as Element.Fixes _) = SOME e |
157 | filter_element (Element.Constrains []) = NONE |
158 | filter_element (Element.Constrains []) = NONE |
158 | filter_element (e as Element.Constrains _) = SOME e |
159 | filter_element (e as Element.Constrains _) = SOME e |
159 | filter_element (Element.Assumes []) = NONE |
160 | filter_element (Element.Assumes []) = NONE |
160 | filter_element (e as Element.Assumes _) = SOME e |
161 | filter_element (e as Element.Assumes _) = SOME e |
161 | filter_element (Element.Defines _) = error ("\"defines\" element not allowed in class specification.") |
162 | filter_element (Element.Defines _) = |
162 | filter_element (Element.Notes _) = error ("\"notes\" element not allowed in class specification."); |
163 error ("\"defines\" element not allowed in class specification.") |
|
164 | filter_element (Element.Notes _) = |
|
165 error ("\"notes\" element not allowed in class specification."); |
163 val inferred_elems = map_filter filter_element raw_inferred_elems; |
166 val inferred_elems = map_filter filter_element raw_inferred_elems; |
164 fun fold_element_types f (Element.Fixes fxs) = fold (fn (_, SOME T, _) => f T) fxs |
167 fun fold_element_types f (Element.Fixes fxs) = fold (fn (_, SOME T, _) => f T) fxs |
165 | fold_element_types f (Element.Constrains cnstrs) = fold (f o snd) cnstrs |
168 | fold_element_types f (Element.Constrains cnstrs) = fold (f o snd) cnstrs |
166 | fold_element_types f (Element.Assumes assms) = fold (fold (fn (t, ts) => |
169 | fold_element_types f (Element.Assumes assms) = fold (fold (fn (t, ts) => |
167 fold_types f t #> (fold o fold_types) f ts) o snd) assms; |
170 fold_types f t #> (fold o fold_types) f ts) o snd) assms; |
168 val base_sort = if null inferred_elems then proto_base_sort else |
171 val base_sort = |
169 case (fold o fold_element_types) Term.add_tfreesT inferred_elems [] |
172 if null inferred_elems then proto_base_sort |
170 of [] => error "No type variable in class specification" |
173 else |
|
174 (case (fold o fold_element_types) Term.add_tfreesT inferred_elems [] of |
|
175 [] => error "No type variable in class specification" |
171 | [(_, sort)] => sort |
176 | [(_, sort)] => sort |
172 | _ => error "Multiple type variables in class specification"; |
177 | _ => error "Multiple type variables in class specification"); |
173 val supparams = map (fn ((c, T), _) => |
178 val supparams = map (fn ((c, T), _) => |
174 (c, map_atyps (K (TFree (Name.aT, base_sort))) T)) raw_supparams; |
179 (c, map_atyps (K (TFree (Name.aT, base_sort))) T)) raw_supparams; |
175 val supparam_names = map fst supparams; |
180 val supparam_names = map fst supparams; |
176 fun mk_param ((c, _), _) = Free (c, (the o AList.lookup (op =) supparams) c); |
181 fun mk_param ((c, _), _) = Free (c, (the o AList.lookup (op =) supparams) c); |
177 val supexpr = (map (fn sup => (sup, (("", false), |
182 val supexpr = (map (fn sup => (sup, (("", false), |