src/Pure/Isar/overloading.ML
author haftmann
Tue, 08 Jan 2008 11:37:27 +0100
changeset 25861 494d9301cc75
parent 25606 23d34f86b88f
child 26238 c30bb8182da2
permissions -rw-r--r--
refined overloading target
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
     1
(*  Title:      Pure/Isar/overloading.ML
8570745cb40b overloading target
haftmann
parents:
diff changeset
     2
    ID:         $Id$
8570745cb40b overloading target
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
8570745cb40b overloading target
haftmann
parents:
diff changeset
     4
8570745cb40b overloading target
haftmann
parents:
diff changeset
     5
Overloaded definitions without any discipline.
8570745cb40b overloading target
haftmann
parents:
diff changeset
     6
*)
8570745cb40b overloading target
haftmann
parents:
diff changeset
     7
8570745cb40b overloading target
haftmann
parents:
diff changeset
     8
signature OVERLOADING =
8570745cb40b overloading target
haftmann
parents:
diff changeset
     9
sig
25861
494d9301cc75 refined overloading target
haftmann
parents: 25606
diff changeset
    10
  val init: (string * (string * typ) * bool) list -> theory -> local_theory
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
    11
  val conclude: local_theory -> local_theory
8570745cb40b overloading target
haftmann
parents:
diff changeset
    12
  val declare: string * typ -> theory -> term * theory
8570745cb40b overloading target
haftmann
parents:
diff changeset
    13
  val confirm: string -> local_theory -> local_theory
8570745cb40b overloading target
haftmann
parents:
diff changeset
    14
  val define: bool -> string -> string * term -> theory -> thm * theory
8570745cb40b overloading target
haftmann
parents:
diff changeset
    15
  val operation: Proof.context -> string -> (string * bool) option
25606
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
    16
  val pretty: Proof.context -> Pretty.T
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
    17
end;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    18
8570745cb40b overloading target
haftmann
parents:
diff changeset
    19
structure Overloading: OVERLOADING =
8570745cb40b overloading target
haftmann
parents:
diff changeset
    20
struct
8570745cb40b overloading target
haftmann
parents:
diff changeset
    21
8570745cb40b overloading target
haftmann
parents:
diff changeset
    22
(* bookkeeping *)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    23
8570745cb40b overloading target
haftmann
parents:
diff changeset
    24
structure OverloadingData = ProofDataFun
8570745cb40b overloading target
haftmann
parents:
diff changeset
    25
(
8570745cb40b overloading target
haftmann
parents:
diff changeset
    26
  type T = ((string * typ) * (string * bool)) list;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    27
  fun init _ = [];
8570745cb40b overloading target
haftmann
parents:
diff changeset
    28
);
8570745cb40b overloading target
haftmann
parents:
diff changeset
    29
8570745cb40b overloading target
haftmann
parents:
diff changeset
    30
val get_overloading = OverloadingData.get o LocalTheory.target_of;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    31
val map_overloading = LocalTheory.target o OverloadingData.map;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    32
8570745cb40b overloading target
haftmann
parents:
diff changeset
    33
fun operation lthy v = get_overloading lthy
8570745cb40b overloading target
haftmann
parents:
diff changeset
    34
  |> get_first (fn ((c, _), (v', checked)) => if v = v' then SOME (c, checked) else NONE);
8570745cb40b overloading target
haftmann
parents:
diff changeset
    35
8570745cb40b overloading target
haftmann
parents:
diff changeset
    36
fun confirm c = map_overloading (filter_out (fn (_, (c', _)) => c' = c));
8570745cb40b overloading target
haftmann
parents:
diff changeset
    37
8570745cb40b overloading target
haftmann
parents:
diff changeset
    38
8570745cb40b overloading target
haftmann
parents:
diff changeset
    39
(* overloaded declarations and definitions *)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    40
8570745cb40b overloading target
haftmann
parents:
diff changeset
    41
fun declare c_ty = pair (Const c_ty);
8570745cb40b overloading target
haftmann
parents:
diff changeset
    42
8570745cb40b overloading target
haftmann
parents:
diff changeset
    43
fun define checked name (c, t) =
8570745cb40b overloading target
haftmann
parents:
diff changeset
    44
  Thm.add_def (not checked) true (name, Logic.mk_equals (Const (c, Term.fastype_of t), t));
8570745cb40b overloading target
haftmann
parents:
diff changeset
    45
8570745cb40b overloading target
haftmann
parents:
diff changeset
    46
8570745cb40b overloading target
haftmann
parents:
diff changeset
    47
(* syntax *)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    48
25536
01753a944433 improved
haftmann
parents: 25519
diff changeset
    49
fun subst_operation overloading = map_aterms (fn t as Const (c, ty) =>
01753a944433 improved
haftmann
parents: 25519
diff changeset
    50
    (case AList.lookup (op =) overloading (c, ty)
01753a944433 improved
haftmann
parents: 25519
diff changeset
    51
     of SOME (v, _) => Free (v, ty)
01753a944433 improved
haftmann
parents: 25519
diff changeset
    52
      | NONE => t)
01753a944433 improved
haftmann
parents: 25519
diff changeset
    53
  | t => t);
01753a944433 improved
haftmann
parents: 25519
diff changeset
    54
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
    55
fun term_check ts lthy =
8570745cb40b overloading target
haftmann
parents:
diff changeset
    56
  let
8570745cb40b overloading target
haftmann
parents:
diff changeset
    57
    val overloading = get_overloading lthy;
25536
01753a944433 improved
haftmann
parents: 25519
diff changeset
    58
    val ts' = map (subst_operation overloading) ts;
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
    59
  in if eq_list (op aconv) (ts, ts') then NONE else SOME (ts', lthy) end;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    60
8570745cb40b overloading target
haftmann
parents:
diff changeset
    61
fun term_uncheck ts lthy =
8570745cb40b overloading target
haftmann
parents:
diff changeset
    62
  let
8570745cb40b overloading target
haftmann
parents:
diff changeset
    63
    val overloading = get_overloading lthy;
25606
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
    64
    fun subst (t as Free (v, ty)) = (case get_first (fn ((c, _), (v', _)) =>
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
    65
        if v = v' then SOME c else NONE) overloading
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
    66
         of SOME c => Const (c, ty)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    67
          | NONE => t)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    68
      | subst t = t;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    69
    val ts' = (map o map_aterms) subst ts;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    70
  in if eq_list (op aconv) (ts, ts') then NONE else SOME (ts', lthy) end;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    71
8570745cb40b overloading target
haftmann
parents:
diff changeset
    72
8570745cb40b overloading target
haftmann
parents:
diff changeset
    73
(* target *)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    74
8570745cb40b overloading target
haftmann
parents:
diff changeset
    75
fun init overloading thy =
8570745cb40b overloading target
haftmann
parents:
diff changeset
    76
  let
8570745cb40b overloading target
haftmann
parents:
diff changeset
    77
    val _ = if null overloading then error "At least one parameter must be given" else ();
8570745cb40b overloading target
haftmann
parents:
diff changeset
    78
  in
8570745cb40b overloading target
haftmann
parents:
diff changeset
    79
    thy
8570745cb40b overloading target
haftmann
parents:
diff changeset
    80
    |> ProofContext.init
25861
494d9301cc75 refined overloading target
haftmann
parents: 25606
diff changeset
    81
    |> OverloadingData.put (map (fn (v, c_ty, checked) => (c_ty, (v, checked))) overloading)
494d9301cc75 refined overloading target
haftmann
parents: 25606
diff changeset
    82
    |> fold (fn (v, (_, ty), _) => Variable.declare_term (Free (v, ty))) overloading
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
    83
    |> Context.proof_map (
8570745cb40b overloading target
haftmann
parents:
diff changeset
    84
        Syntax.add_term_check 0 "overloading" term_check
8570745cb40b overloading target
haftmann
parents:
diff changeset
    85
        #> Syntax.add_term_uncheck 0 "overloading" term_uncheck)
8570745cb40b overloading target
haftmann
parents:
diff changeset
    86
  end;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    87
8570745cb40b overloading target
haftmann
parents:
diff changeset
    88
fun conclude lthy =
8570745cb40b overloading target
haftmann
parents:
diff changeset
    89
  let
8570745cb40b overloading target
haftmann
parents:
diff changeset
    90
    val overloading = get_overloading lthy;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    91
    val _ = if null overloading then () else
8570745cb40b overloading target
haftmann
parents:
diff changeset
    92
      error ("Missing definition(s) for parameters " ^ commas (map (quote
8570745cb40b overloading target
haftmann
parents:
diff changeset
    93
        o Syntax.string_of_term lthy o Const o fst) overloading));
8570745cb40b overloading target
haftmann
parents:
diff changeset
    94
  in
8570745cb40b overloading target
haftmann
parents:
diff changeset
    95
    lthy
8570745cb40b overloading target
haftmann
parents:
diff changeset
    96
  end;
8570745cb40b overloading target
haftmann
parents:
diff changeset
    97
25606
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
    98
fun pretty lthy =
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
    99
  let
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   100
    val thy = ProofContext.theory_of lthy;
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   101
    val overloading = get_overloading lthy;
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   102
    fun pr_operation ((c, ty), (v, _)) =
25861
494d9301cc75 refined overloading target
haftmann
parents: 25606
diff changeset
   103
      (Pretty.block o Pretty.breaks) [Pretty.str v, Pretty.str "==",
494d9301cc75 refined overloading target
haftmann
parents: 25606
diff changeset
   104
        Pretty.str (Sign.extern_const thy c), Pretty.str "::", Sign.pretty_typ thy ty];
25606
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   105
  in
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   106
    (Pretty.block o Pretty.fbreaks)
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   107
      (Pretty.str "overloading" :: map pr_operation overloading)
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   108
  end;
23d34f86b88f continued
haftmann
parents: 25536
diff changeset
   109
25519
8570745cb40b overloading target
haftmann
parents:
diff changeset
   110
end;