src/Pure/Isar/class_declaration.ML
changeset 45421 2bef6da4a6a6
parent 42494 eef1a23c9077
child 45429 fd58cbf8cae3
equal deleted inserted replaced
45420:d17556b9a89b 45421:2bef6da4a6a6
   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),
   315 val class_cmd = gen_class read_class_spec;
   320 val class_cmd = gen_class read_class_spec;
   316 
   321 
   317 end; (*local*)
   322 end; (*local*)
   318 
   323 
   319 
   324 
       
   325 
   320 (** subclass relations **)
   326 (** subclass relations **)
   321 
   327 
   322 local
   328 local
   323 
   329 
   324 fun gen_subclass prep_class do_proof before_exit raw_sup lthy =
   330 fun gen_subclass prep_class do_proof before_exit raw_sup lthy =