src/Pure/Isar/class.ML
changeset 38382 8b02c5bf1d0e
parent 38381 7d1e2a6831ec
child 38384 07c33be08476
equal deleted inserted replaced
38381:7d1e2a6831ec 38382:8b02c5bf1d0e
   439     |> Overloading.map_improvable_syntax
   439     |> Overloading.map_improvable_syntax
   440          (fn (((primary_constraints, _), (((improve, _), _), _)), _) =>
   440          (fn (((primary_constraints, _), (((improve, _), _), _)), _) =>
   441             (((primary_constraints, []), (((improve, subst), false), unchecks)), false))
   441             (((primary_constraints, []), (((improve, subst), false), unchecks)), false))
   442   end;
   442   end;
   443 
   443 
   444 
       
   445 (* target *)
       
   446 
       
   447 val sanitize_name = (*necessary as long as "dirty" type identifiers are permitted*)
       
   448   let
       
   449     fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s
       
   450       orelse s = "'" orelse s = "_";
       
   451     val is_junk = not o is_valid andf Symbol.is_regular;
       
   452     val junk = Scan.many is_junk;
       
   453     val scan_valids = Symbol.scanner "Malformed input"
       
   454       ((junk |--
       
   455         (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
       
   456         --| junk))
       
   457       ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk));
       
   458   in
       
   459     explode #> scan_valids #> implode
       
   460   end;
       
   461 
       
   462 val type_name = sanitize_name o Long_Name.base_name;
       
   463 
       
   464 fun resort_terms pp algebra consts constraints ts =
   444 fun resort_terms pp algebra consts constraints ts =
   465   let
   445   let
   466     fun matchings (Const (c_ty as (c, _))) = (case constraints c
   446     fun matchings (Const (c_ty as (c, _))) = (case constraints c
   467          of NONE => I
   447          of NONE => I
   468           | SOME sorts => fold2 (curry (Sorts.meet_sort algebra))
   448           | SOME sorts => fold2 (curry (Sorts.meet_sort algebra))
   472       handle Sorts.CLASS_ERROR e => error (Sorts.class_error pp e);
   452       handle Sorts.CLASS_ERROR e => error (Sorts.class_error pp e);
   473     val inst = map_type_tvar
   453     val inst = map_type_tvar
   474       (fn (vi, sort) => TVar (vi, the_default sort (Vartab.lookup tvartab vi)));
   454       (fn (vi, sort) => TVar (vi, the_default sort (Vartab.lookup tvartab vi)));
   475   in if Vartab.is_empty tvartab then NONE else SOME ((map o map_types) inst ts) end;
   455   in if Vartab.is_empty tvartab then NONE else SOME ((map o map_types) inst ts) end;
   476 
   456 
   477 fun init_instantiation (tycos, vs, sort) thy =
   457 
       
   458 (* target *)
       
   459 
       
   460 val sanitize_name = (*necessary as long as "dirty" type identifiers are permitted*)
       
   461   let
       
   462     fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s
       
   463       orelse s = "'" orelse s = "_";
       
   464     val is_junk = not o is_valid andf Symbol.is_regular;
       
   465     val junk = Scan.many is_junk;
       
   466     val scan_valids = Symbol.scanner "Malformed input"
       
   467       ((junk |--
       
   468         (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
       
   469         --| junk))
       
   470       ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk));
       
   471   in
       
   472     explode #> scan_valids #> implode
       
   473   end;
       
   474 
       
   475 val type_name = sanitize_name o Long_Name.base_name;
       
   476 
       
   477 fun define_overloaded (c, U) v (b_def, rhs) = Local_Theory.theory_result
       
   478     (AxClass.declare_overloaded (c, U) ##>> AxClass.define_overloaded b_def (c, rhs))
       
   479   ##> (map_instantiation o apsnd) (filter_out (fn (_, (v', _)) => v' = v))
       
   480   ##> Local_Theory.target synchronize_inst_syntax;
       
   481 
       
   482 fun foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy =
       
   483   case instantiation_param lthy b
       
   484    of SOME c => if mx <> NoSyn then error ("Illegal mixfix syntax for overloaded constant " ^ quote c)
       
   485         else lthy |> define_overloaded (c, U) (Binding.name_of b) (b_def, rhs)
       
   486     | NONE => lthy |>
       
   487         Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params);
       
   488 
       
   489 fun pretty lthy =
       
   490   let
       
   491     val { arities = (tycos, vs, sort), params } = the_instantiation lthy;
       
   492     val thy = ProofContext.theory_of lthy;
       
   493     fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort);
       
   494     fun pr_param ((c, _), (v, ty)) =
       
   495       (Pretty.block o Pretty.breaks) [Pretty.str v, Pretty.str "==",
       
   496         (Pretty.str o Sign.extern_const thy) c, Pretty.str "::", Syntax.pretty_typ_global thy ty];
       
   497   in Pretty.str "instantiation" :: map pr_arity tycos @ map pr_param params end;
       
   498 
       
   499 fun conclude lthy =
       
   500   let
       
   501     val (tycos, vs, sort) = (#arities o the_instantiation) lthy;
       
   502     val thy = ProofContext.theory_of lthy;
       
   503     val _ = map (fn tyco => if Sign.of_sort thy
       
   504         (Type (tyco, map TFree vs), sort)
       
   505       then () else error ("Missing instance proof for type " ^ quote (Sign.extern_type thy tyco)))
       
   506         tycos;
       
   507   in lthy end;
       
   508 
       
   509 fun instantiation (tycos, vs, sort) thy =
   478   let
   510   let
   479     val _ = if null tycos then error "At least one arity must be given" else ();
   511     val _ = if null tycos then error "At least one arity must be given" else ();
   480     val class_params = these_params thy (filter (can (AxClass.get_info thy)) sort);
   512     val class_params = these_params thy (filter (can (AxClass.get_info thy)) sort);
   481     fun get_param tyco (param, (_, (c, ty))) =
   513     fun get_param tyco (param, (_, (c, ty))) =
   482       if can (AxClass.param_of_inst thy) (c, tyco)
   514       if can (AxClass.param_of_inst thy) (c, tyco)
   510     |> (Overloading.map_improvable_syntax o apfst)
   542     |> (Overloading.map_improvable_syntax o apfst)
   511          (K ((primary_constraints, []), (((improve, K NONE), false), [])))
   543          (K ((primary_constraints, []), (((improve, K NONE), false), [])))
   512     |> Overloading.add_improvable_syntax
   544     |> Overloading.add_improvable_syntax
   513     |> Context.proof_map (Syntax.add_term_check 0 "resorting" resort_check)
   545     |> Context.proof_map (Syntax.add_term_check 0 "resorting" resort_check)
   514     |> synchronize_inst_syntax
   546     |> synchronize_inst_syntax
   515   end;
   547     |> Local_Theory.init NONE ""
   516 
   548        {define = Generic_Target.define foundation,
   517 fun confirm_declaration b = (map_instantiation o apsnd)
   549         notes = Generic_Target.notes
   518   (filter_out (fn (_, (c', _)) => c' = Binding.name_of b))
   550           (fn kind => fn global_facts => fn _ => Generic_Target.theory_notes kind global_facts),
   519   #> Local_Theory.target synchronize_inst_syntax
   551         abbrev = Generic_Target.abbrev
       
   552           (fn prmode => fn (b, mx) => fn (t, _) => fn _ => Generic_Target.theory_abbrev prmode ((b, mx), t)),
       
   553         declaration = K Generic_Target.theory_declaration,
       
   554         syntax_declaration = K Generic_Target.theory_declaration,
       
   555         pretty = pretty,
       
   556         exit = Local_Theory.target_of o conclude}
       
   557   end;
       
   558 
       
   559 fun instantiation_cmd arities thy =
       
   560   instantiation (read_multi_arity thy arities) thy;
   520 
   561 
   521 fun gen_instantiation_instance do_proof after_qed lthy =
   562 fun gen_instantiation_instance do_proof after_qed lthy =
   522   let
   563   let
   523     val (tycos, vs, sort) = (#arities o the_instantiation) lthy;
   564     val (tycos, vs, sort) = (#arities o the_instantiation) lthy;
   524     val arities_proof = maps (fn tyco => Logic.mk_arities (tyco, map snd vs, sort)) tycos;
   565     val arities_proof = maps (fn tyco => Logic.mk_arities (tyco, map snd vs, sort)) tycos;
   549     lthy
   590     lthy
   550     |> prove_instantiation_exit (fn ctxt => tac ctxt y)
   591     |> prove_instantiation_exit (fn ctxt => tac ctxt y)
   551     |> pair y
   592     |> pair y
   552   end;
   593   end;
   553 
   594 
   554 fun conclude_instantiation lthy =
       
   555   let
       
   556     val (tycos, vs, sort) = (#arities o the_instantiation) lthy;
       
   557     val thy = ProofContext.theory_of lthy;
       
   558     val _ = map (fn tyco => if Sign.of_sort thy
       
   559         (Type (tyco, map TFree vs), sort)
       
   560       then () else error ("Missing instance proof for type " ^ quote (Sign.extern_type thy tyco)))
       
   561         tycos;
       
   562   in lthy end;
       
   563 
       
   564 fun pretty_instantiation lthy =
       
   565   let
       
   566     val { arities = (tycos, vs, sort), params } = the_instantiation lthy;
       
   567     val thy = ProofContext.theory_of lthy;
       
   568     fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort);
       
   569     fun pr_param ((c, _), (v, ty)) =
       
   570       (Pretty.block o Pretty.breaks) [Pretty.str v, Pretty.str "==",
       
   571         (Pretty.str o Sign.extern_const thy) c, Pretty.str "::", Syntax.pretty_typ_global thy ty];
       
   572   in
       
   573     (Pretty.block o Pretty.fbreaks)
       
   574       (Pretty.str "instantiation" :: map pr_arity tycos @ map pr_param params)
       
   575   end;
       
   576 
       
   577 fun syntax_error c = error ("Illegal mixfix syntax for overloaded constant " ^ quote c);
       
   578 
       
   579 fun instantiation_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy =
       
   580   case instantiation_param lthy b
       
   581    of SOME c => if mx <> NoSyn then syntax_error c
       
   582         else lthy |> Local_Theory.theory_result (AxClass.declare_overloaded (c, U)
       
   583             ##>> AxClass.define_overloaded b_def (c, rhs))
       
   584           ||> confirm_declaration b
       
   585     | NONE => lthy |>
       
   586         Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params);
       
   587 
       
   588 fun instantiation arities thy =
       
   589   thy
       
   590   |> init_instantiation arities
       
   591   |> Local_Theory.init NONE ""
       
   592      {define = Generic_Target.define instantiation_foundation,
       
   593       notes = Generic_Target.notes
       
   594         (fn kind => fn global_facts => fn _ => Generic_Target.theory_notes kind global_facts),
       
   595       abbrev = Generic_Target.abbrev
       
   596         (fn prmode => fn (b, mx) => fn (t, _) => fn _ => Generic_Target.theory_abbrev prmode ((b, mx), t)),
       
   597       declaration = K Generic_Target.theory_declaration,
       
   598       syntax_declaration = K Generic_Target.theory_declaration,
       
   599       pretty = single o pretty_instantiation,
       
   600       exit = Local_Theory.target_of o conclude_instantiation};
       
   601 
       
   602 fun instantiation_cmd arities thy =
       
   603   instantiation (read_multi_arity thy arities) thy;
       
   604 
       
   605 
   595 
   606 (* simplified instantiation interface with no class parameter *)
   596 (* simplified instantiation interface with no class parameter *)
   607 
   597 
   608 fun instance_arity_cmd raw_arities thy =
   598 fun instance_arity_cmd raw_arities thy =
   609   let
   599   let