src/HOL/Types_To_Sets/unoverloading.ML
author nipkow
Fri, 11 Dec 2020 17:58:01 +0100
changeset 72884 50f18a822ee9
parent 69597 ff784d5a5bfb
child 77808 b43ee37926a9
permissions -rw-r--r--
merged
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
64551
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     1
(*  Title:      HOL/Types_To_Sets/unoverloading.ML
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     2
    Author:     Ondřej Kunčar, TU München
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     3
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     4
The Unoverloading Rule (extension of the logic).
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     5
*)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     6
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     7
signature UNOVERLOADING =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     8
sig
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
     9
  val unoverload: cterm -> thm -> thm
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    10
  val unoverload_attr: cterm -> attribute
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    11
end;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    12
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    13
structure Unoverloading : UNOVERLOADING =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    14
struct
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    15
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    16
(*
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    17
Unoverloading Rule (UO)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    18
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    19
      \<turnstile> \<phi>[c::\<sigma> / x::\<sigma>]
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    20
---------------------------- [no type or constant or type class in \<phi>
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    21
        \<turnstile> \<And>x::\<sigma>. \<phi>           depends on c::\<sigma>; c::\<sigma> is undefined]
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    22
*)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    23
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    24
(* The following functions match_args, reduction and entries_of were
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    25
   cloned from defs.ML and theory.ML because the functions are not public.
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    26
   Notice that these functions already belong to the critical code.
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    27
*)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    28
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    29
(* >= *)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    30
fun match_args (Ts, Us) =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    31
  if Type.could_matches (Ts, Us) then
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    32
    Option.map Envir.subst_type
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    33
      (SOME (Type.raw_matches (Ts, Us) Vartab.empty) handle Type.TYPE_MATCH => NONE)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    34
  else NONE;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    35
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    36
fun reduction defs (deps : Defs.entry list) : Defs.entry list option =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    37
  let
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    38
    fun reduct Us (Ts, rhs) =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    39
      (case match_args (Ts, Us) of
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    40
        NONE => NONE
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    41
      | SOME subst => SOME (map (apsnd (map subst)) rhs));
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    42
    fun reducts (d, Us) = get_first (reduct Us) (Defs.get_deps defs d);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    43
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    44
    val reds = map (`reducts) deps;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    45
    val deps' =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    46
      if forall (is_none o #1) reds then NONE
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    47
      else SOME (fold_rev
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    48
        (fn (NONE, dp) => insert (op =) dp | (SOME dps, _) => fold (insert (op =)) dps) reds []);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    49
  in deps' end;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    50
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    51
fun const_and_typ_entries_of thy tm =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    52
 let
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    53
   val consts =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    54
     fold_aterms (fn Const const => insert (op =) (Theory.const_dep thy const) | _ => I) tm [];
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    55
   val types =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    56
     (fold_types o fold_subtypes) (fn Type t => insert (op =) (Theory.type_dep t) | _ => I) tm [];
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    57
 in
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    58
   consts @ types
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    59
 end;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    60
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    61
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    62
(* The actual implementation *)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    63
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    64
(** BEGINNING OF THE CRITICAL CODE **)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    65
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    66
fun fold_atyps_classes f =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    67
  fold_atyps (fn T as TFree (_, S) => fold (pair T #> f) S
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    68
    | T as TVar (_, S) => fold (pair T #> f) S
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    69
    (* just to avoid a warning about incomplete patterns *)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    70
    | _ => raise TERM ("fold_atyps_classes", []));
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    71
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    72
fun class_entries_of thy tm =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    73
  let
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    74
    val var_classes = (fold_types o fold_atyps_classes) (insert op=) tm [];
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    75
  in
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    76
    map (Logic.mk_of_class #> Term.head_of #> Term.dest_Const #> Theory.const_dep thy) var_classes
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    77
  end;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    78
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    79
fun unoverload_impl cconst thm =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    80
  let
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    81
    fun err msg = raise THM ("unoverloading: " ^ msg, 0, [thm]);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    82
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    83
    val _ = null (Thm.hyps_of thm) orelse err "the theorem has meta hypotheses";
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    84
    val _ = null (Thm.tpairs_of thm) orelse err "the theorem contains unresolved flex-flex pairs";
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    85
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    86
    val prop = Thm.prop_of thm;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    87
    val prop_tfrees = rev (Term.add_tfree_names prop []);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    88
    val _ = null prop_tfrees orelse err ("the theorem contains free type variables "
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    89
      ^ commas_quote prop_tfrees);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    90
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    91
    val const = Thm.term_of cconst;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    92
    val _ = Term.is_Const const orelse err "the parameter is is not a constant";
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    93
    val const_tfrees = rev (Term.add_tfree_names const []);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    94
    val _ = null const_tfrees orelse err ("the constant contains free type variables "
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    95
      ^ commas_quote const_tfrees);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    96
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    97
    val thy = Thm.theory_of_thm thm;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    98
    val defs = Theory.defs_of thy;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
    99
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   100
    val const_entry = Theory.const_dep thy (Term.dest_Const const);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   101
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   102
    val Uss = Defs.specifications_of defs (fst const_entry);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   103
    val _ = forall (fn spec => is_none (match_args (#lhs spec, snd const_entry))) Uss
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   104
      orelse err "the constant instance has already a specification";
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   105
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   106
    val context = Defs.global_context thy;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   107
    val prt_entry = Pretty.string_of o Defs.pretty_entry context;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   108
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   109
    fun dep_err (c, Ts) (d, Us) =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   110
      err (prt_entry (c, Ts) ^ " depends on " ^ prt_entry (d, Us));
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   111
    fun deps_of entry = perhaps_loop (reduction defs) [entry] |> these;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   112
    fun not_depends_on_const prop_entry = forall (not_equal const_entry) (deps_of prop_entry)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   113
      orelse dep_err prop_entry const_entry;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   114
    val prop_entries = const_and_typ_entries_of thy prop @ class_entries_of thy prop;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   115
    val _ = forall not_depends_on_const prop_entries;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   116
  in
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   117
    Thm.global_cterm_of thy (Logic.all const prop) |> Thm.weaken_sorts (Thm.shyps_of thm)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   118
  end;
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   119
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   120
(** END OF THE CRITICAL CODE **)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   121
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   122
val (_, unoverload_oracle) = Context.>>> (Context.map_theory_result
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 64551
diff changeset
   123
  (Thm.add_oracle (\<^binding>\<open>unoverload\<close>,
64551
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   124
  fn (const, thm) => unoverload_impl const  thm)));
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   125
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   126
fun unoverload const thm = unoverload_oracle (const, thm);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   127
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   128
fun unoverload_attr const =
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   129
  Thm.rule_attribute [] (fn _ => fn thm => (unoverload const thm));
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   130
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   131
val const = Args.context -- Args.term  >>
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   132
  (fn (ctxt, tm) =>
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   133
    if not (Term.is_Const tm)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   134
    then error ("The term is not a constant: " ^ Syntax.string_of_term ctxt tm)
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   135
    else tm |> Logic.varify_types_global |> Thm.cterm_of ctxt);
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   136
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 64551
diff changeset
   137
val _ = Context.>> (Context.map_theory (Attrib.setup \<^binding>\<open>unoverload\<close>
64551
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   138
  (const >> unoverload_attr) "unoverload an uninterpreted constant"));
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   139
79e9587dbcca proper session HOL-Types_To_Sets;
wenzelm
parents:
diff changeset
   140
end;