src/Pure/Tools/adhoc_overloading.ML
author haftmann
Thu, 19 Jun 2025 17:15:40 +0200
changeset 82734 89347c0cc6a3
parent 82008 7301923ad1e9
permissions -rw-r--r--
treat map_filter similar to list_all, list_ex, list_ex1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
81989
96afb0707532 move theory "HOL-Library.Adhoc_Overloading" to Pure;
wenzelm
parents: 81253
diff changeset
     1
(*  Title:      Pure/Tools/adhoc_overloading.ML
96afb0707532 move theory "HOL-Library.Adhoc_Overloading" to Pure;
wenzelm
parents: 81253
diff changeset
     2
    Author:     Alexander Krauss, TU Muenchen
53538
4e9e150422d5 tuned whitespace;
wenzelm
parents: 53537
diff changeset
     3
    Author:     Christian Sternagel, University of Innsbruck
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     4
52893
aa2afbafd983 use uniform spelling of "adhoc"
Christian Sternagel
parents: 52892
diff changeset
     5
Adhoc overloading of constants based on their types.
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     6
*)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     7
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     8
signature ADHOC_OVERLOADING =
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     9
sig
81989
96afb0707532 move theory "HOL-Library.Adhoc_Overloading" to Pure;
wenzelm
parents: 81253
diff changeset
    10
  val show_variants: bool Config.T
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
    11
  val adhoc_overloading: bool -> (string * term list) list -> local_theory -> local_theory
81989
96afb0707532 move theory "HOL-Library.Adhoc_Overloading" to Pure;
wenzelm
parents: 81253
diff changeset
    12
  val adhoc_overloading_cmd: bool -> (string * string list) list -> local_theory -> local_theory
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    13
end
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    14
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    15
structure Adhoc_Overloading: ADHOC_OVERLOADING =
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    16
struct
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    17
69593
3dda49e08b9d isabelle update -u control_cartouches;
wenzelm
parents: 68061
diff changeset
    18
val show_variants = Attrib.setup_config_bool \<^binding>\<open>show_variants\<close> (K false);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    19
53538
4e9e150422d5 tuned whitespace;
wenzelm
parents: 53537
diff changeset
    20
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    21
(* errors *)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    22
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
    23
fun err_duplicate_variant oconst =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    24
  error ("Duplicate variant of " ^ quote oconst);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    25
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
    26
fun err_not_a_variant oconst =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    27
  error ("Not a variant of " ^  quote oconst);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    28
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
    29
fun err_not_overloaded oconst =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    30
  error ("Constant " ^ quote oconst ^ " is not declared as overloaded");
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    31
53540
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    32
fun err_unresolved_overloading ctxt0 (c, T) t instances =
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    33
  let
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    34
    val ctxt = Config.put show_variants true ctxt0
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    35
    val const_space = Proof_Context.const_space ctxt
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    36
    val prt_const =
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    37
      Pretty.block [Name_Space.pretty ctxt const_space c, Pretty.str " ::", Pretty.brk 1,
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    38
        Pretty.quote (Syntax.pretty_typ ctxt T)]
52688
1e13b2515e2b show variants in error messages; more precise error messages (give witnesses for multiple instances)
Christian Sternagel
parents: 52687
diff changeset
    39
  in
53537
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    40
    error (Pretty.string_of (Pretty.chunks [
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    41
      Pretty.block [
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    42
        Pretty.str "Unresolved adhoc overloading of constant", Pretty.brk 1,
53540
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    43
        prt_const, Pretty.brk 1, Pretty.str "in term", Pretty.brk 1,
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    44
        Pretty.block [Pretty.quote (Syntax.pretty_term ctxt t)]],
53537
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    45
      Pretty.block (
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    46
        (if null instances then [Pretty.str "no instances"]
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    47
        else Pretty.fbreaks (
addbc2387c61 tuned message;
wenzelm
parents: 53008
diff changeset
    48
          Pretty.str "multiple instances:" ::
53540
7903fe2c271b prefer explicit type constraint (again, see also Type.appl_error);
wenzelm
parents: 53538
diff changeset
    49
          map (Pretty.mark Markup.item o Syntax.pretty_term ctxt) instances)))]))
52688
1e13b2515e2b show variants in error messages; more precise error messages (give witnesses for multiple instances)
Christian Sternagel
parents: 52687
diff changeset
    50
  end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    51
53538
4e9e150422d5 tuned whitespace;
wenzelm
parents: 53537
diff changeset
    52
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    53
(* generic data *)
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    54
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    55
fun variants_eq ((v1, T1), (v2, T2)) =
81991
c61434d8558e tuned signature: more explicit Type.raw_equiv;
wenzelm
parents: 81990
diff changeset
    56
  Term.aconv_untyped (v1, v2) andalso Type.raw_equiv (T1, T2);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    57
82000
67cfa8e9435e tuned names;
wenzelm
parents: 81994
diff changeset
    58
structure Data = Generic_Data
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    59
(
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    60
  type T =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    61
    {variants : (term * typ) list Symtab.table,
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    62
     oconsts : string Termtab.table};
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
    63
  val empty : T = {variants = Symtab.empty, oconsts = Termtab.empty};
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    64
41472
f6ab14e61604 misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents: 37818
diff changeset
    65
  fun merge
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    66
    ({variants = vtab1, oconsts = otab1},
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    67
     {variants = vtab2, oconsts = otab2}) : T =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    68
    let
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
    69
      fun join (oconst1, oconst2) =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    70
        if oconst1 = oconst2 then oconst1
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
    71
        else err_duplicate_variant oconst1;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    72
    in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    73
      {variants = Symtab.merge_list variants_eq (vtab1, vtab2),
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
    74
       oconsts = Termtab.join (K join) (otab1, otab2)}
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    75
    end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    76
);
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    77
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
    78
fun map_data f =
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
    79
  Data.map (fn {variants, oconsts} =>
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
    80
    let val (variants', oconsts') = f (variants, oconsts)
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
    81
    in {variants = variants', oconsts = oconsts'} end);
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    82
82005
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
    83
val no_variants = Symtab.is_empty o #variants o Data.get;
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
    84
val has_variants = Symtab.defined o #variants o Data.get;
82001
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
    85
val get_variants = Symtab.lookup o #variants o Data.get;
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
    86
val get_overloaded = Termtab.lookup o #oconsts o Data.get;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    87
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    88
fun generic_add_overloaded oconst context =
82005
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
    89
  if has_variants context oconst then context
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
    90
  else (map_data o apfst) (Symtab.update (oconst, [])) context;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    91
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
    92
(*If the list of variants is empty at the end of "generic_remove_variant", then
82000
67cfa8e9435e tuned names;
wenzelm
parents: 81994
diff changeset
    93
  "generic_remove_overloaded" is called implicitly.*)
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    94
fun generic_remove_overloaded oconst context =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    95
  let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    96
    fun remove_oconst_and_variants context oconst =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    97
      let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    98
        val remove_variants =
82001
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
    99
          (case get_variants context oconst of
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   100
            NONE => I
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   101
          | SOME vs => fold (Termtab.remove (op =) o rpair oconst o fst) vs);
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   102
      in
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   103
        context |> map_data (fn (variants, oconsts) =>
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   104
          (Symtab.delete_safe oconst variants, remove_variants oconsts))
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   105
      end;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   106
  in
82005
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
   107
    if has_variants context oconst then remove_oconst_and_variants context oconst
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
   108
    else err_not_overloaded oconst
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   109
  end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   110
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   111
local
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   112
  fun generic_variant add oconst t context =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   113
    let
82005
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
   114
      val _ = if has_variants context oconst then () else err_not_overloaded oconst;
82008
wenzelm
parents: 82007
diff changeset
   115
      val T = fastype_of t;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   116
      val t' = Term.map_types (K dummyT) t;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   117
    in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   118
      if add then
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   119
        let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   120
          val _ =
82001
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
   121
            (case get_overloaded context t' of
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   122
              NONE => ()
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
   123
            | SOME oconst' => err_duplicate_variant oconst');
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   124
        in
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   125
          context |> map_data (fn (variants, oconsts) =>
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   126
            (Symtab.cons_list (oconst, (t', T)) variants, Termtab.update (t', oconst) oconsts))
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   127
        end
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   128
      else
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   129
        let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   130
          val _ =
82001
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
   131
            if member variants_eq (the (get_variants context oconst)) (t', T) then ()
53008
128bec4e3fca indicate error-functions more prominently (by name prefix instead of suffix);
Christian Sternagel
parents: 53007
diff changeset
   132
            else err_not_a_variant oconst;
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   133
          val context' =
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   134
            context |> map_data (fn (variants, oconsts) =>
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   135
              (Symtab.map_entry oconst (remove1 variants_eq (t', T)) variants,
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   136
               Termtab.delete_safe t' oconsts));
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   137
        in
82003
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   138
          (case get_variants context' oconst of
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   139
            SOME [] => generic_remove_overloaded oconst context'
abb40413c1e7 clarified signature: more standard map_data;
wenzelm
parents: 82002
diff changeset
   140
          | _ => context')
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   141
        end
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   142
    end;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   143
in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   144
  val generic_add_variant = generic_variant true;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   145
  val generic_remove_variant = generic_variant false;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   146
end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   147
53538
4e9e150422d5 tuned whitespace;
wenzelm
parents: 53537
diff changeset
   148
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   149
(* check / uncheck *)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   150
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   151
local
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   152
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   153
fun unifiable_types ctxt (T1, T2) =
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   154
  let
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   155
    val thy = Proof_Context.theory_of ctxt;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   156
    val maxidx1 = Term.maxidx_of_typ T1;
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   157
    val T2' = Logic.incr_tvar (maxidx1 + 1) T2;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   158
    val maxidx2 = Term.maxidx_typ T2' maxidx1;
53004
38165b99562e clarify function;
Christian Sternagel
parents: 52893
diff changeset
   159
  in can (Sign.typ_unify thy (T1, T2')) (Vartab.empty, maxidx2) end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   160
53006
83d9984ee639 avoid misleading "instances" in function name;
Christian Sternagel
parents: 53005
diff changeset
   161
fun get_candidates ctxt (c, T) =
82001
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
   162
  get_variants (Context.Proof ctxt) c
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   163
  |> Option.map (map_filter (fn (t, T') =>
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   164
    if unifiable_types ctxt (T, T')
80127
39f9084a9668 make adhoc_overloading respect type constraints
Kevin Kappelmann <kevin.kappelmann@tum.de>
parents: 78095
diff changeset
   165
    (*keep the type constraint for the type-inference check phase*)
39f9084a9668 make adhoc_overloading respect type constraints
Kevin Kappelmann <kevin.kappelmann@tum.de>
parents: 78095
diff changeset
   166
    then SOME (Type.constraint T t)
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   167
    else NONE));
52687
72cda5eb5a39 refactoring
Christian Sternagel
parents: 52622
diff changeset
   168
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   169
val the_candidates = the oo get_candidates;
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   170
82007
04c704a6b193 minor performance tuning;
wenzelm
parents: 82006
diff changeset
   171
fun insert_variants_same ctxt t : term Same.operation =
04c704a6b193 minor performance tuning;
wenzelm
parents: 82006
diff changeset
   172
  (fn Const const =>
04c704a6b193 minor performance tuning;
wenzelm
parents: 82006
diff changeset
   173
      (case get_candidates ctxt const of
04c704a6b193 minor performance tuning;
wenzelm
parents: 82006
diff changeset
   174
        SOME [] => err_unresolved_overloading ctxt const t []
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   175
      | SOME [variant] => variant
82007
04c704a6b193 minor performance tuning;
wenzelm
parents: 82006
diff changeset
   176
      | _ => raise Same.SAME)
04c704a6b193 minor performance tuning;
wenzelm
parents: 82006
diff changeset
   177
    | _ => raise Same.SAME);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   178
54004
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   179
fun insert_overloaded ctxt =
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   180
  let
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   181
    val thy = Proof_Context.theory_of ctxt;
54004
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   182
    fun proc t =
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   183
      Term.map_types (K dummyT) t
82001
ae454f0c4f4c clarified signature with minor performance tuning: avoid Context.proof_of with its Proof_Context.init_global;
wenzelm
parents: 82000
diff changeset
   184
      |> get_overloaded (Context.Proof ctxt)
54004
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   185
      |> Option.map (Const o rpair (Term.type_of t));
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   186
  in
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   187
    Pattern.rewrite_term_yoyo thy [] [proc]
54004
e13b0c88c798 preserve types during rewriting
Christian Sternagel
parents: 53540
diff changeset
   188
  end;
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   189
82008
wenzelm
parents: 82007
diff changeset
   190
fun overloaded_term_consts ctxt =
82004
aaa7e388265a minor performance tuning: avoid somewhat indirect filter / add_consts;
wenzelm
parents: 82003
diff changeset
   191
  let
aaa7e388265a minor performance tuning: avoid somewhat indirect filter / add_consts;
wenzelm
parents: 82003
diff changeset
   192
    val context = Context.Proof ctxt;
82005
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
   193
    val overloaded = has_variants context;
82008
wenzelm
parents: 82007
diff changeset
   194
    val add = fn Const (c, T) => if overloaded c then insert (op =) (c, T) else I | _ => I;
wenzelm
parents: 82007
diff changeset
   195
  in fn t => if no_variants context then [] else fold_aterms add t [] end;
82004
aaa7e388265a minor performance tuning: avoid somewhat indirect filter / add_consts;
wenzelm
parents: 82003
diff changeset
   196
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   197
in
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   198
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   199
fun check ctxt =
82005
b2d8d50b9efb tuned names;
wenzelm
parents: 82004
diff changeset
   200
  if no_variants (Context.Proof ctxt) then I
82008
wenzelm
parents: 82007
diff changeset
   201
  else map (fn t => t |> Term.map_aterms (insert_variants_same ctxt t));
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   202
54468
f6ffe53387ef reintroduced e2d08b9c9047, lost in 54e290da6da8 + e13b0c88c798
traytel
parents: 54004
diff changeset
   203
fun uncheck ctxt ts =
82006
wenzelm
parents: 82005
diff changeset
   204
  if Config.get ctxt show_variants orelse exists (not o can Term.type_of) ts then ts
54468
f6ffe53387ef reintroduced e2d08b9c9047, lost in 54e290da6da8 + e13b0c88c798
traytel
parents: 54004
diff changeset
   205
  else map (insert_overloaded ctxt) ts;
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   206
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   207
fun reject_unresolved ctxt =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   208
  let
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   209
    fun check_unresolved t =
82008
wenzelm
parents: 82007
diff changeset
   210
      (case overloaded_term_consts ctxt t of
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   211
        [] => t
82004
aaa7e388265a minor performance tuning: avoid somewhat indirect filter / add_consts;
wenzelm
parents: 82003
diff changeset
   212
      | const :: _ => err_unresolved_overloading ctxt const t (the_candidates ctxt const));
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   213
  in map check_unresolved end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   214
82002
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   215
end;
150bbde003ef misc tuning;
wenzelm
parents: 82001
diff changeset
   216
53538
4e9e150422d5 tuned whitespace;
wenzelm
parents: 53537
diff changeset
   217
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   218
(* setup *)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   219
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   220
val _ = Context.>>
53007
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   221
  (Syntax_Phases.term_check 0 "adhoc_overloading" check
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   222
   #> Syntax_Phases.term_check 1 "adhoc_overloading_unresolved_check" reject_unresolved
54e290da6da8 avoid low-level Same structure;
Christian Sternagel
parents: 53006
diff changeset
   223
   #> Syntax_Phases.term_uncheck 0 "adhoc_overloading" uncheck);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   224
53538
4e9e150422d5 tuned whitespace;
wenzelm
parents: 53537
diff changeset
   225
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   226
(* commands *)
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   227
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   228
local
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   229
81994
5e50a2b52809 support for "no" polarity of 'adhoc_overloading' vs. 'no_adhoc_overloading';
wenzelm
parents: 81992
diff changeset
   230
fun generic_adhoc_overloading add args context =
5e50a2b52809 support for "no" polarity of 'adhoc_overloading' vs. 'no_adhoc_overloading';
wenzelm
parents: 81992
diff changeset
   231
  if Syntax.effective_polarity_generic context add then
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   232
    fold (fn (oconst, ts) =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   233
      generic_add_overloaded oconst
81994
5e50a2b52809 support for "no" polarity of 'adhoc_overloading' vs. 'no_adhoc_overloading';
wenzelm
parents: 81992
diff changeset
   234
      #> fold (generic_add_variant oconst) ts) args context
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   235
  else
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   236
    fold (fn (oconst, ts) =>
81994
5e50a2b52809 support for "no" polarity of 'adhoc_overloading' vs. 'no_adhoc_overloading';
wenzelm
parents: 81992
diff changeset
   237
      fold (generic_remove_variant oconst) ts) args context;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   238
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   239
fun gen_adhoc_overloading prep_arg add raw_args lthy =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   240
  let
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   241
    val args = map (prep_arg lthy) raw_args;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   242
  in
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   243
    lthy |> Local_Theory.declaration {syntax = true, pervasive = false, pos = Position.thread_data ()}
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   244
      (fn phi =>
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   245
        let val args' = args
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   246
          |> map (apsnd (map_filter (fn t =>
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   247
               let val t' = Morphism.term phi t;
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   248
               in if Term.aconv_untyped (t, t') then SOME t' else NONE end)));
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   249
        in generic_adhoc_overloading add args' end)
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   250
  end;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   251
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   252
fun cert_const_name ctxt c =
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   253
  (Consts.the_const_type (Proof_Context.consts_of ctxt) c; c);
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   254
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   255
fun read_const_name ctxt =
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   256
  dest_Const_name o Proof_Context.read_const {proper = true, strict = true} ctxt;
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   257
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   258
fun cert_term ctxt = Proof_Context.cert_term ctxt #> singleton (Variable.polymorphic ctxt);
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   259
fun read_term ctxt = Syntax.read_term ctxt #> singleton (Variable.polymorphic ctxt);
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   260
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   261
in
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   262
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   263
val adhoc_overloading =
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   264
  gen_adhoc_overloading (fn ctxt => fn (c, ts) => (cert_const_name ctxt c, map (cert_term ctxt) ts));
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   265
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   266
val adhoc_overloading_cmd =
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   267
  gen_adhoc_overloading (fn ctxt => fn (c, ts) => (read_const_name ctxt c, map (read_term ctxt) ts));
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   268
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   269
end;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   270
81992
be1328008ee2 clarified signature: proper ML interface to main command, without exposing too many internals;
wenzelm
parents: 81991
diff changeset
   271
end;