src/Tools/adhoc_overloading.ML
author wenzelm
Fri, 12 Jul 2013 16:19:05 +0200
changeset 52622 e0ff1625e96d
parent 50768 2172f82de515
child 52687 72cda5eb5a39
permissions -rw-r--r--
localized and modernized adhoc-overloading (patch by Christian Sternagel);
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     1
(* Author: Alexander Krauss, TU Muenchen
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     2
   Author: Christian Sternagel, University of Innsbruck
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     3
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     4
Ad-hoc overloading of constants based on their types.
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     5
*)
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
signature ADHOC_OVERLOADING =
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
     8
sig
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
     9
  val is_overloaded: Proof.context -> string -> bool
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    10
  val generic_add_overloaded: string -> Context.generic -> Context.generic
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    11
  val generic_remove_overloaded: string -> Context.generic -> Context.generic
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    12
  val generic_add_variant: string -> term -> Context.generic -> Context.generic
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    13
  (*If the list of variants is empty at the end of "generic_remove_variant", then
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    14
  "generic_remove_overloaded" is called implicitly.*)
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    15
  val generic_remove_variant: string -> term -> Context.generic -> Context.generic
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
    16
  val show_variants: bool Config.T
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    17
end
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    18
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    19
structure Adhoc_Overloading: ADHOC_OVERLOADING =
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    20
struct
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    21
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
    22
val show_variants = Attrib.setup_config_bool @{binding show_variants} (K false);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    23
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    24
(* errors *)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    25
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    26
fun duplicate_variant_error oconst =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    27
  error ("Duplicate variant of " ^ quote oconst);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    28
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    29
fun not_a_variant_error oconst =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    30
  error ("Not a variant of " ^  quote oconst);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    31
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    32
fun not_overloaded_error oconst =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    33
  error ("Constant " ^ quote oconst ^ " is not declared as overloaded");
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    34
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    35
fun unresolved_overloading_error ctxt (c, T) t reason =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    36
  error ("Unresolved overloading of " ^ quote c ^ " :: " ^
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    37
    quote (Syntax.string_of_typ ctxt T) ^ " in " ^
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    38
    quote (Syntax.string_of_term ctxt t) ^ " (" ^ reason ^ ")");
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    39
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    40
(* generic data *)
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    41
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    42
fun variants_eq ((v1, T1), (v2, T2)) =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    43
  Term.aconv_untyped (v1, v2) andalso T1 = T2;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    44
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    45
structure Overload_Data = Generic_Data
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    46
(
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    47
  type T =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    48
    {variants : (term * typ) list Symtab.table,
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    49
     oconsts : string Termtab.table};
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    50
  val empty = {variants = Symtab.empty, oconsts = Termtab.empty};
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    51
  val extend = I;
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    52
41472
f6ab14e61604 misc tuning and comments based on review of Theory_Data, Proof_Data, Generic_Data usage;
wenzelm
parents: 37818
diff changeset
    53
  fun merge
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    54
    ({variants = vtab1, oconsts = otab1},
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    55
     {variants = vtab2, oconsts = otab2}) : T =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    56
    let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    57
      fun merge_oconsts _ (oconst1, oconst2) =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    58
        if oconst1 = oconst2 then oconst1
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    59
        else duplicate_variant_error oconst1;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    60
    in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    61
      {variants = Symtab.merge_list variants_eq (vtab1, vtab2),
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    62
       oconsts = Termtab.join merge_oconsts (otab1, otab2)}
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    63
    end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    64
);
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    65
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    66
fun map_tables f g =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    67
  Overload_Data.map (fn {variants = vtab, oconsts = otab} =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    68
    {variants = f vtab, oconsts = g otab});
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    69
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    70
val is_overloaded = Symtab.defined o #variants o Overload_Data.get o Context.Proof;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    71
val get_variants = Symtab.lookup o #variants o Overload_Data.get o Context.Proof;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    72
val get_overloaded = Termtab.lookup o #oconsts o Overload_Data.get o Context.Proof;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    73
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    74
fun generic_add_overloaded oconst context =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    75
  if is_overloaded (Context.proof_of context) oconst then context
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    76
  else map_tables (Symtab.update (oconst, [])) I context;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    77
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    78
fun generic_remove_overloaded oconst context =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    79
  let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    80
    fun remove_oconst_and_variants context oconst =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    81
      let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    82
        val remove_variants =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    83
          (case get_variants (Context.proof_of context) oconst of
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    84
            NONE => I
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    85
          | SOME vs => fold (Termtab.remove (op =) o rpair oconst o fst) vs);
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    86
      in map_tables (Symtab.delete_safe oconst) remove_variants context end;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    87
  in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    88
    if is_overloaded (Context.proof_of context) oconst then remove_oconst_and_variants context oconst
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    89
    else not_overloaded_error oconst
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    90
  end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
    91
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    92
local
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    93
  fun generic_variant add oconst t context =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    94
    let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    95
      val ctxt = Context.proof_of context;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    96
      val _ = if is_overloaded ctxt oconst then () else not_overloaded_error oconst;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    97
      val T = t |> singleton (Variable.polymorphic ctxt) |> fastype_of;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    98
      val t' = Term.map_types (K dummyT) t;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
    99
    in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   100
      if add then
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   101
        let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   102
          val _ =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   103
            (case get_overloaded ctxt t' of
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   104
              NONE => ()
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   105
            | SOME oconst' => duplicate_variant_error oconst');
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   106
        in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   107
          map_tables (Symtab.cons_list (oconst, (t', T))) (Termtab.update (t', oconst)) context
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   108
        end
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   109
      else
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   110
        let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   111
          val _ =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   112
            if member variants_eq (the (get_variants ctxt oconst)) (t', T) then ()
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   113
            else not_a_variant_error oconst;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   114
        in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   115
          map_tables (Symtab.map_entry oconst (remove1 variants_eq (t', T)))
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   116
            (Termtab.delete_safe t') context
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   117
          |> (fn context =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   118
            (case get_variants (Context.proof_of context) oconst of
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   119
              SOME [] => generic_remove_overloaded oconst context
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   120
            | _ => context))
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   121
        end
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   122
    end;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   123
in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   124
  val generic_add_variant = generic_variant true;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   125
  val generic_remove_variant = generic_variant false;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   126
end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   127
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   128
(* check / uncheck *)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   129
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   130
fun unifiable_with thy T1 (t, T2) =
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   131
  let
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   132
    val maxidx1 = Term.maxidx_of_typ T1;
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   133
    val T2' = Logic.incr_tvar (maxidx1 + 1) T2;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   134
    val maxidx2 = Term.maxidx_typ T2' maxidx1;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   135
  in
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   136
    (Sign.typ_unify thy (T1, T2') (Vartab.empty, maxidx2); SOME t)
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   137
    handle Type.TUNIFY => NONE
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   138
  end;
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   139
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   140
fun insert_variants_same ctxt t (Const (c, T)) =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   141
      (case map_filter (unifiable_with (Proof_Context.theory_of ctxt) T)
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   142
         (Same.function (get_variants ctxt) c) of
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   143
        [] => unresolved_overloading_error ctxt (c, T) t "no instances"
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   144
      | [variant] => variant
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   145
      | _ => raise Same.SAME)
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   146
  | insert_variants_same _ _ _ = raise Same.SAME;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   147
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   148
fun insert_overloaded_same ctxt variant =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   149
  let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   150
    val thy = Proof_Context.theory_of ctxt;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   151
    val t = Pattern.rewrite_term thy [] [fn t =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   152
      Term.map_types (K dummyT) t
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   153
      |> get_overloaded ctxt
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   154
      |> Option.map (Const o rpair (fastype_of variant))] variant;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   155
  in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   156
    if Term.aconv_untyped (variant, t) then raise Same.SAME
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   157
    else t
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   158
  end;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   159
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   160
fun gen_check_uncheck replace ts ctxt =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   161
  Same.capture (Same.map replace) ts
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   162
  |> Option.map (rpair ctxt);
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   163
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   164
fun check ts ctxt = gen_check_uncheck (fn t =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   165
  Term_Subst.map_aterms_same (insert_variants_same ctxt t) t) ts ctxt;
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   166
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   167
fun uncheck ts ctxt =
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   168
  if Config.get ctxt show_variants then NONE
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   169
  else gen_check_uncheck (insert_overloaded_same ctxt) ts ctxt;
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   170
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   171
fun reject_unresolved ts ctxt =
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   172
  let
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   173
    fun check_unresolved t =
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   174
      (case filter (is_overloaded ctxt o fst) (Term.add_consts t []) of
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   175
        [] => ()
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   176
      | ((c, T) :: _) => unresolved_overloading_error ctxt (c, T) t "multiple instances");
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   177
    val _ = map check_unresolved ts;
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   178
  in NONE end;
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   179
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   180
(* setup *)
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   181
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   182
val _ = Context.>>
45444
ac069060e08a tuned signature;
wenzelm
parents: 45429
diff changeset
   183
  (Syntax_Phases.term_check' 0 "adhoc_overloading" check
ac069060e08a tuned signature;
wenzelm
parents: 45429
diff changeset
   184
   #> Syntax_Phases.term_check' 1 "adhoc_overloading_unresolved_check" reject_unresolved
ac069060e08a tuned signature;
wenzelm
parents: 45429
diff changeset
   185
   #> Syntax_Phases.term_uncheck' 0 "adhoc_overloading" uncheck);
37789
93f6dcf9ec02 generic ad-hoc overloading via check/uncheck
krauss
parents:
diff changeset
   186
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   187
(* commands *)
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   188
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   189
fun generic_adhoc_overloading_cmd add =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   190
  if add then
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   191
    fold (fn (oconst, ts) =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   192
      generic_add_overloaded oconst
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   193
      #> fold (generic_add_variant oconst) ts)
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   194
  else
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   195
    fold (fn (oconst, ts) =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   196
      fold (generic_remove_variant oconst) ts);
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   197
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   198
fun adhoc_overloading_cmd' add args phi =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   199
  let val args' = args
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   200
    |> map (apsnd (map_filter (fn t =>
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   201
         let val t' = Morphism.term phi t;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   202
         in if Term.aconv_untyped (t, t') then SOME t' else NONE end)));
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   203
  in generic_adhoc_overloading_cmd add args' end;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   204
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   205
fun adhoc_overloading_cmd add raw_args lthy =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   206
  let
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   207
    fun const_name ctxt = fst o dest_Const o Proof_Context.read_const ctxt false dummyT;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   208
    val args =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   209
      raw_args
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   210
      |> map (apfst (const_name lthy))
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   211
      |> map (apsnd (map (Syntax.read_term lthy)));
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   212
  in
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   213
    Local_Theory.declaration {syntax = true, pervasive = false}
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   214
      (adhoc_overloading_cmd' add args) lthy
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   215
  end;
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   216
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   217
val _ =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   218
  Outer_Syntax.local_theory @{command_spec "adhoc_overloading"}
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   219
    "add ad-hoc overloading for constants / fixed variables"
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   220
    (Parse.and_list1 (Parse.const -- Scan.repeat Parse.term) >> adhoc_overloading_cmd true);
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   221
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   222
val _ =
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   223
  Outer_Syntax.local_theory @{command_spec "no_adhoc_overloading"}
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   224
    "add ad-hoc overloading for constants / fixed variables"
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   225
    (Parse.and_list1 (Parse.const -- Scan.repeat Parse.term) >> adhoc_overloading_cmd false);
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   226
45422
711dac69111b proper configuration option;
wenzelm
parents: 42402
diff changeset
   227
end;
52622
e0ff1625e96d localized and modernized adhoc-overloading (patch by Christian Sternagel);
wenzelm
parents: 50768
diff changeset
   228