src/Pure/Isar/class.ML
changeset 46919 82fc322fc30a
parent 46917 2f6c1952188a
child 46923 947f63062022
equal deleted inserted replaced
46918:1752164d916b 46919:82fc322fc30a
    54 structure Class: CLASS =
    54 structure Class: CLASS =
    55 struct
    55 struct
    56 
    56 
    57 (** class data **)
    57 (** class data **)
    58 
    58 
    59 datatype class_data = ClassData of {
    59 datatype class_data = Class_Data of {
    60 
    60 
    61   (* static part *)
    61   (* static part *)
    62   consts: (string * string) list
    62   consts: (string * string) list
    63     (*locale parameter ~> constant name*),
    63     (*locale parameter ~> constant name*),
    64   base_sort: sort,
    64   base_sort: sort,
    75 
    75 
    76 };
    76 };
    77 
    77 
    78 fun make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom),
    78 fun make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom),
    79     (defs, operations)) =
    79     (defs, operations)) =
    80   ClassData { consts = consts, base_sort = base_sort,
    80   Class_Data {consts = consts, base_sort = base_sort,
    81     base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro,
    81     base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro,
    82     of_class = of_class, axiom = axiom, defs = defs, operations = operations };
    82     of_class = of_class, axiom = axiom, defs = defs, operations = operations};
    83 fun map_class_data f (ClassData { consts, base_sort, base_morph, export_morph, assm_intro,
    83 fun map_class_data f (Class_Data {consts, base_sort, base_morph, export_morph, assm_intro,
    84     of_class, axiom, defs, operations }) =
    84     of_class, axiom, defs, operations}) =
    85   make_class_data (f ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom),
    85   make_class_data (f ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom),
    86     (defs, operations)));
    86     (defs, operations)));
    87 fun merge_class_data _ (ClassData { consts = consts,
    87 fun merge_class_data _ (Class_Data {consts = consts,
    88     base_sort = base_sort, base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro,
    88     base_sort = base_sort, base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro,
    89     of_class = of_class, axiom = axiom, defs = defs1, operations = operations1 },
    89     of_class = of_class, axiom = axiom, defs = defs1, operations = operations1},
    90   ClassData { consts = _, base_sort = _, base_morph = _, export_morph = _, assm_intro = _,
    90   Class_Data {consts = _, base_sort = _, base_morph = _, export_morph = _, assm_intro = _,
    91     of_class = _, axiom = _, defs = defs2, operations = operations2 }) =
    91     of_class = _, axiom = _, defs = defs2, operations = operations2}) =
    92   make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom),
    92   make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom),
    93     (Thm.merge_thms (defs1, defs2),
    93     (Thm.merge_thms (defs1, defs2),
    94       AList.merge (op =) (K true) (operations1, operations2)));
    94       AList.merge (op =) (K true) (operations1, operations2)));
    95 
    95 
    96 structure ClassData = Theory_Data
    96 structure Class_Data = Theory_Data
    97 (
    97 (
    98   type T = class_data Graph.T
    98   type T = class_data Graph.T
    99   val empty = Graph.empty;
    99   val empty = Graph.empty;
   100   val extend = I;
   100   val extend = I;
   101   val merge = Graph.join merge_class_data;
   101   val merge = Graph.join merge_class_data;
   102 );
   102 );
   103 
   103 
   104 
   104 
   105 (* queries *)
   105 (* queries *)
   106 
   106 
   107 fun lookup_class_data thy class = case try (Graph.get_node (ClassData.get thy)) class
   107 fun lookup_class_data thy class =
   108  of SOME (ClassData data) => SOME data
   108   (case try (Graph.get_node (Class_Data.get thy)) class of
   109   | NONE => NONE;
   109     SOME (Class_Data data) => SOME data
   110 
   110   | NONE => NONE);
   111 fun the_class_data thy class = case lookup_class_data thy class
   111 
   112  of NONE => error ("Undeclared class " ^ quote class)
   112 fun the_class_data thy class =
   113   | SOME data => data;
   113   (case lookup_class_data thy class of
       
   114     NONE => error ("Undeclared class " ^ quote class)
       
   115   | SOME data => data);
   114 
   116 
   115 val is_class = is_some oo lookup_class_data;
   117 val is_class = is_some oo lookup_class_data;
   116 
   118 
   117 val ancestry = Graph.all_succs o ClassData.get;
   119 val ancestry = Graph.all_succs o Class_Data.get;
   118 val heritage = Graph.all_preds o ClassData.get;
   120 val heritage = Graph.all_preds o Class_Data.get;
   119 
   121 
   120 fun these_params thy =
   122 fun these_params thy =
   121   let
   123   let
   122     fun params class =
   124     fun params class =
   123       let
   125       let
   130   in maps params o ancestry thy end;
   132   in maps params o ancestry thy end;
   131 
   133 
   132 val base_sort = #base_sort oo the_class_data;
   134 val base_sort = #base_sort oo the_class_data;
   133 
   135 
   134 fun rules thy class =
   136 fun rules thy class =
   135   let val { axiom, of_class, ... } = the_class_data thy class
   137   let val {axiom, of_class, ...} = the_class_data thy class
   136   in (axiom, of_class) end;
   138   in (axiom, of_class) end;
   137 
   139 
   138 fun all_assm_intros thy =
   140 fun all_assm_intros thy =
   139   Graph.fold (fn (_, (ClassData { assm_intro, ... }, _)) => fold (insert Thm.eq_thm)
   141   Graph.fold (fn (_, (Class_Data {assm_intro, ...}, _)) => fold (insert Thm.eq_thm)
   140     (the_list assm_intro)) (ClassData.get thy) [];
   142     (the_list assm_intro)) (Class_Data.get thy) [];
   141 
   143 
   142 fun these_defs thy = maps (#defs o the_class_data thy) o ancestry thy;
   144 fun these_defs thy = maps (#defs o the_class_data thy) o ancestry thy;
   143 fun these_operations thy = maps (#operations o the_class_data thy) o ancestry thy;
   145 fun these_operations thy = maps (#operations o the_class_data thy) o ancestry thy;
   144 
   146 
   145 val base_morphism = #base_morph oo the_class_data;
   147 val base_morphism = #base_morph oo the_class_data;
   146 fun morphism thy class = case Element.eq_morphism thy (these_defs thy [class])
   148 fun morphism thy class =
   147  of SOME eq_morph => base_morphism thy class $> eq_morph
   149   (case Element.eq_morphism thy (these_defs thy [class]) of
   148   | NONE => base_morphism thy class;
   150     SOME eq_morph => base_morphism thy class $> eq_morph
       
   151   | NONE => base_morphism thy class);
   149 val export_morphism = #export_morph oo the_class_data;
   152 val export_morphism = #export_morph oo the_class_data;
   150 
   153 
   151 fun print_classes ctxt =
   154 fun print_classes ctxt =
   152   let
   155   let
   153     val thy = Proof_Context.theory_of ctxt;
   156     val thy = Proof_Context.theory_of ctxt;
   192       (c, (class, (ty, Free v_ty)))) params;
   195       (c, (class, (ty, Free v_ty)))) params;
   193     val add_class = Graph.new_node (class,
   196     val add_class = Graph.new_node (class,
   194         make_class_data (((map o pairself) fst params, base_sort,
   197         make_class_data (((map o pairself) fst params, base_sort,
   195           base_morph, export_morph, assm_intro, of_class, axiom), ([], operations)))
   198           base_morph, export_morph, assm_intro, of_class, axiom), ([], operations)))
   196       #> fold (curry Graph.add_edge class) sups;
   199       #> fold (curry Graph.add_edge class) sups;
   197   in ClassData.map add_class thy end;
   200   in Class_Data.map add_class thy end;
   198 
   201 
   199 fun activate_defs class thms thy = case Element.eq_morphism thy thms
   202 fun activate_defs class thms thy =
   200  of SOME eq_morph => fold (fn cls => fn thy =>
   203   (case Element.eq_morphism thy thms of
       
   204     SOME eq_morph => fold (fn cls => fn thy =>
   201       Context.theory_map (Locale.amend_registration (cls, base_morphism thy cls)
   205       Context.theory_map (Locale.amend_registration (cls, base_morphism thy cls)
   202         (eq_morph, true) (export_morphism thy cls)) thy) (heritage thy [class]) thy
   206         (eq_morph, true) (export_morphism thy cls)) thy) (heritage thy [class]) thy
   203   | NONE => thy;
   207   | NONE => thy);
   204 
   208 
   205 fun register_operation class (c, (t, some_def)) thy =
   209 fun register_operation class (c, (t, some_def)) thy =
   206   let
   210   let
   207     val base_sort = base_sort thy class;
   211     val base_sort = base_sort thy class;
   208     val prep_typ = map_type_tfree
   212     val prep_typ = map_type_tfree
   210         then TFree (v, base_sort) else TVar ((v, 0), sort));
   214         then TFree (v, base_sort) else TVar ((v, 0), sort));
   211     val t' = map_types prep_typ t;
   215     val t' = map_types prep_typ t;
   212     val ty' = Term.fastype_of t';
   216     val ty' = Term.fastype_of t';
   213   in
   217   in
   214     thy
   218     thy
   215     |> (ClassData.map o Graph.map_node class o map_class_data o apsnd)
   219     |> (Class_Data.map o Graph.map_node class o map_class_data o apsnd)
   216       (fn (defs, operations) =>
   220       (fn (defs, operations) =>
   217         (fold cons (the_list some_def) defs,
   221         (fold cons (the_list some_def) defs,
   218           (c, (class, (ty', t'))) :: operations))
   222           (c, (class, (ty', t'))) :: operations))
   219     |> activate_defs class (the_list some_def)
   223     |> activate_defs class (the_list some_def)
   220   end;
   224   end;
   228     val classrel = Skip_Proof.prove_global thy [] [] (Logic.mk_classrel (sub, sup))
   232     val classrel = Skip_Proof.prove_global thy [] [] (Logic.mk_classrel (sub, sup))
   229       (K tac);
   233       (K tac);
   230     val diff_sort = Sign.complete_sort thy [sup]
   234     val diff_sort = Sign.complete_sort thy [sup]
   231       |> subtract (op =) (Sign.complete_sort thy [sub])
   235       |> subtract (op =) (Sign.complete_sort thy [sub])
   232       |> filter (is_class thy);
   236       |> filter (is_class thy);
   233     val add_dependency = case some_dep_morph
   237     val add_dependency =
   234      of SOME dep_morph => Locale.add_dependency sub
   238       (case some_dep_morph of
       
   239         SOME dep_morph => Locale.add_dependency sub
   235           (sup, dep_morph $> Element.satisfy_morphism (the_list some_wit)) NONE export
   240           (sup, dep_morph $> Element.satisfy_morphism (the_list some_wit)) NONE export
   236       | NONE => I
   241       | NONE => I);
   237   in
   242   in
   238     thy
   243     thy
   239     |> AxClass.add_classrel classrel
   244     |> AxClass.add_classrel classrel
   240     |> ClassData.map (Graph.add_edge (sub, sup))
   245     |> Class_Data.map (Graph.add_edge (sub, sup))
   241     |> activate_defs sub (these_defs thy diff_sort)
   246     |> activate_defs sub (these_defs thy diff_sort)
   242     |> add_dependency
   247     |> add_dependency
   243   end;
   248   end;
   244 
   249 
   245 
   250 
   262     fun subst_class_typ sort = map_type_tfree (K (TVar ((Name.aT, 0), sort)));
   267     fun subst_class_typ sort = map_type_tfree (K (TVar ((Name.aT, 0), sort)));
   263     val primary_constraints =
   268     val primary_constraints =
   264       (map o apsnd) (subst_class_typ base_sort o fst o snd) operations;
   269       (map o apsnd) (subst_class_typ base_sort o fst o snd) operations;
   265     val secondary_constraints =
   270     val secondary_constraints =
   266       (map o apsnd) (fn (class, (ty, _)) => subst_class_typ [class] ty) operations;
   271       (map o apsnd) (fn (class, (ty, _)) => subst_class_typ [class] ty) operations;
   267     fun improve (c, ty) = (case AList.lookup (op =) primary_constraints c
   272     fun improve (c, ty) =
   268      of SOME ty' => (case try (Type.raw_match (ty', ty)) Vartab.empty
   273       (case AList.lookup (op =) primary_constraints c of
   269          of SOME tyenv => (case Vartab.lookup tyenv (Name.aT, 0)
   274         SOME ty' =>
   270              of SOME (_, ty' as TVar (vi, sort)) =>
   275           (case try (Type.raw_match (ty', ty)) Vartab.empty of
   271                   if Type_Infer.is_param vi
   276             SOME tyenv =>
   272                     andalso Sorts.sort_le algebra (base_sort, sort)
   277               (case Vartab.lookup tyenv (Name.aT, 0) of
   273                       then SOME (ty', TFree (Name.aT, base_sort))
   278                 SOME (_, ty' as TVar (vi, sort)) =>
   274                       else NONE
   279                   if Type_Infer.is_param vi andalso Sorts.sort_le algebra (base_sort, sort)
       
   280                   then SOME (ty', TFree (Name.aT, base_sort))
       
   281                   else NONE
   275               | _ => NONE)
   282               | _ => NONE)
   276           | NONE => NONE)
   283           | NONE => NONE)
   277       | NONE => NONE)
   284       | NONE => NONE);
   278     fun subst (c, ty) = Option.map snd (AList.lookup (op =) operations c);
   285     fun subst (c, ty) = Option.map snd (AList.lookup (op =) operations c);
   279     val unchecks = these_unchecks thy sort;
   286     val unchecks = these_unchecks thy sort;
   280   in
   287   in
   281     ctxt
   288     ctxt
   282     |> fold (redeclare_const thy o fst) primary_constraints
   289     |> fold (redeclare_const thy o fst) primary_constraints
   395     (*(instantiation parameter, type constructor), (local instantiation parameter, typ)*)
   402     (*(instantiation parameter, type constructor), (local instantiation parameter, typ)*)
   396 }
   403 }
   397 
   404 
   398 structure Instantiation = Proof_Data
   405 structure Instantiation = Proof_Data
   399 (
   406 (
   400   type T = instantiation
   407   type T = instantiation;
   401   fun init _ = Instantiation { arities = ([], [], []), params = [] };
   408   fun init _ = Instantiation {arities = ([], [], []), params = []};
   402 );
   409 );
   403 
   410 
   404 fun mk_instantiation (arities, params) =
   411 fun mk_instantiation (arities, params) =
   405   Instantiation { arities = arities, params = params };
   412   Instantiation {arities = arities, params = params};
   406 fun get_instantiation lthy = case Instantiation.get (Local_Theory.target_of lthy)
   413 
   407  of Instantiation data => data;
   414 val get_instantiation =
   408 fun map_instantiation f = (Local_Theory.target o Instantiation.map)
   415   (fn Instantiation data => data) o Instantiation.get o Local_Theory.target_of;
   409   (fn Instantiation { arities, params } => mk_instantiation (f (arities, params)));
   416 
   410 
   417 fun map_instantiation f =
   411 fun the_instantiation lthy = case get_instantiation lthy
   418   (Local_Theory.target o Instantiation.map)
   412  of { arities = ([], [], []), ... } => error "No instantiation target"
   419     (fn Instantiation {arities, params} => mk_instantiation (f (arities, params)));
   413   | data => data;
   420 
       
   421 fun the_instantiation lthy =
       
   422   (case get_instantiation lthy of
       
   423     {arities = ([], [], []), ...} => error "No instantiation target"
       
   424   | data => data);
   414 
   425 
   415 val instantiation_params = #params o get_instantiation;
   426 val instantiation_params = #params o get_instantiation;
   416 
   427 
   417 fun instantiation_param lthy b = instantiation_params lthy
   428 fun instantiation_param lthy b = instantiation_params lthy
   418   |> find_first (fn (_, (v, _)) => Binding.name_of b = v)
   429   |> find_first (fn (_, (v, _)) => Binding.name_of b = v)
   431 
   442 
   432 (* syntax *)
   443 (* syntax *)
   433 
   444 
   434 fun synchronize_inst_syntax ctxt =
   445 fun synchronize_inst_syntax ctxt =
   435   let
   446   let
   436     val Instantiation { params, ... } = Instantiation.get ctxt;
   447     val Instantiation {params, ...} = Instantiation.get ctxt;
   437 
   448 
   438     val lookup_inst_param = AxClass.lookup_inst_param
   449     val lookup_inst_param = AxClass.lookup_inst_param
   439       (Sign.consts_of (Proof_Context.theory_of ctxt)) params;
   450       (Sign.consts_of (Proof_Context.theory_of ctxt)) params;
   440     fun subst (c, ty) = case lookup_inst_param (c, ty)
   451     fun subst (c, ty) =
   441      of SOME (v_ty as (_, ty)) => SOME (ty, Free v_ty)
   452       (case lookup_inst_param (c, ty) of
   442       | NONE => NONE;
   453         SOME (v_ty as (_, ty)) => SOME (ty, Free v_ty)
       
   454       | NONE => NONE);
   443     val unchecks =
   455     val unchecks =
   444       map (fn ((c, _), v_ty as (_, ty)) => (Free v_ty, Const (c, ty))) params;
   456       map (fn ((c, _), v_ty as (_, ty)) => (Free v_ty, Const (c, ty))) params;
   445   in
   457   in
   446     ctxt
   458     ctxt
   447     |> Overloading.map_improvable_syntax
   459     |> Overloading.map_improvable_syntax
   448          (fn (((primary_constraints, _), (((improve, _), _), _)), _) =>
   460       (fn (((primary_constraints, _), (((improve, _), _), _)), _) =>
   449             (((primary_constraints, []), (((improve, subst), false), unchecks)), false))
   461           (((primary_constraints, []), (((improve, subst), false), unchecks)), false))
   450   end;
   462   end;
   451 
   463 
   452 fun resort_terms ctxt algebra consts constraints ts =
   464 fun resort_terms ctxt algebra consts constraints ts =
   453   let
   465   let
   454     fun matchings (Const (c_ty as (c, _))) =
   466     fun matchings (Const (c_ty as (c, _))) =
   470     (AxClass.declare_overloaded (c, U) ##>> AxClass.define_overloaded b_def (c, rhs))
   482     (AxClass.declare_overloaded (c, U) ##>> AxClass.define_overloaded b_def (c, rhs))
   471   ##> (map_instantiation o apsnd) (filter_out (fn (_, (v', _)) => v' = v))
   483   ##> (map_instantiation o apsnd) (filter_out (fn (_, (v', _)) => v' = v))
   472   ##> Local_Theory.target synchronize_inst_syntax;
   484   ##> Local_Theory.target synchronize_inst_syntax;
   473 
   485 
   474 fun foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy =
   486 fun foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy =
   475   case instantiation_param lthy b
   487   (case instantiation_param lthy b of
   476    of SOME c => if mx <> NoSyn then error ("Illegal mixfix syntax for overloaded constant " ^ quote c)
   488     SOME c =>
   477         else lthy |> define_overloaded (c, U) (Binding.name_of b) (b_def, rhs)
   489       if mx <> NoSyn then error ("Illegal mixfix syntax for overloaded constant " ^ quote c)
   478     | NONE => lthy |>
   490       else lthy |> define_overloaded (c, U) (Binding.name_of b) (b_def, rhs)
   479         Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params);
   491   | NONE => lthy |>
       
   492       Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params));
   480 
   493 
   481 fun pretty lthy =
   494 fun pretty lthy =
   482   let
   495   let
   483     val { arities = (tycos, vs, sort), params } = the_instantiation lthy;
   496     val {arities = (tycos, vs, sort), params} = the_instantiation lthy;
   484     fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort);
   497     fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort);
   485     fun pr_param ((c, _), (v, ty)) =
   498     fun pr_param ((c, _), (v, ty)) =
   486       Pretty.block (Pretty.breaks
   499       Pretty.block (Pretty.breaks
   487         [Pretty.str v, Pretty.str "==", Pretty.str (Proof_Context.extern_const lthy c),
   500         [Pretty.str v, Pretty.str "==", Pretty.str (Proof_Context.extern_const lthy c),
   488           Pretty.str "::", Syntax.pretty_typ lthy ty]);
   501           Pretty.str "::", Syntax.pretty_typ lthy ty]);
   491 fun conclude lthy =
   504 fun conclude lthy =
   492   let
   505   let
   493     val (tycos, vs, sort) = #arities (the_instantiation lthy);
   506     val (tycos, vs, sort) = #arities (the_instantiation lthy);
   494     val thy = Proof_Context.theory_of lthy;
   507     val thy = Proof_Context.theory_of lthy;
   495     val _ = tycos |> List.app (fn tyco =>
   508     val _ = tycos |> List.app (fn tyco =>
   496       if Sign.of_sort thy
   509       if Sign.of_sort thy (Type (tyco, map TFree vs), sort) then ()
   497         (Type (tyco, map TFree vs), sort)
       
   498       then ()
       
   499       else error ("Missing instance proof for type " ^ quote (Proof_Context.extern_type lthy tyco)));
   510       else error ("Missing instance proof for type " ^ quote (Proof_Context.extern_type lthy tyco)));
   500   in lthy end;
   511   in lthy end;
   501 
   512 
   502 fun instantiation (tycos, vs, sort) thy =
   513 fun instantiation (tycos, vs, sort) thy =
   503   let
   514   let