src/Pure/Thy/thm_database.ML
author wenzelm
Wed Sep 22 20:58:23 1999 +0200 (1999-09-22)
changeset 7573 aa87cf5a15f5
parent 7446 f43d3670a3cd
child 7609 1acbed762fc6
permissions -rw-r--r--
ml_store_thm: no warning for "";
clasohm@1132
     1
(*  Title:      Pure/Thy/thm_database.ML
clasohm@1132
     2
    ID:         $Id$
wenzelm@4023
     3
    Author:     Carsten Clasohm and Tobias Nipkow and Markus Wenzel, TU Muenchen
clasohm@1132
     4
wenzelm@4023
     5
User level interface to thm database (see also Pure/pure_thy.ML).
wenzelm@4023
     6
*)
clasohm@1262
     7
wenzelm@6204
     8
signature BASIC_THM_DATABASE =
wenzelm@4023
     9
sig
wenzelm@4023
    10
  val store_thm: string * thm -> thm
wenzelm@7410
    11
  val store_thms: string * thm list -> thm list
wenzelm@4023
    12
  val bind_thm: string * thm -> unit
wenzelm@7410
    13
  val bind_thms: string * thm list -> unit
wenzelm@4023
    14
  val qed: string -> unit
wenzelm@4023
    15
  val qed_goal: string -> theory -> string -> (thm list -> tactic list) -> unit
wenzelm@4023
    16
  val qed_goalw: string -> theory -> thm list -> string -> (thm list -> tactic list) -> unit
wenzelm@7446
    17
  val no_qed: unit -> unit
wenzelm@4023
    18
  (*these peek at the proof state!*)
wenzelm@4287
    19
  val thms_containing: xstring list -> (string * thm) list
wenzelm@4023
    20
  val findI: int -> (string * thm) list
wenzelm@4023
    21
  val findEs: int -> (string * thm) list
wenzelm@4023
    22
  val findE: int -> int -> (string * thm) list
wenzelm@4023
    23
end;
clasohm@1132
    24
wenzelm@6204
    25
signature THM_DATABASE =
wenzelm@6204
    26
sig
wenzelm@6204
    27
  include BASIC_THM_DATABASE
wenzelm@7410
    28
  val qed_thms: thm list ref
wenzelm@6204
    29
  val ml_store_thm: string * thm -> unit
wenzelm@7410
    30
  val ml_store_thms: string * thm list -> unit
wenzelm@6204
    31
  val is_ml_identifier: string -> bool
wenzelm@6204
    32
end;
wenzelm@6204
    33
wenzelm@3627
    34
structure ThmDatabase: THM_DATABASE =
nipkow@1221
    35
struct
clasohm@1132
    36
wenzelm@4023
    37
(** store theorems **)
clasohm@1132
    38
wenzelm@4023
    39
(* store in theory and generate HTML *)
clasohm@1136
    40
wenzelm@4023
    41
fun store_thm (name, thm) =
wenzelm@7410
    42
  let val thm' = hd (PureThy.smart_store_thms (name, [thm]))
wenzelm@6327
    43
  in Present.theorem name thm'; thm' end;
clasohm@1132
    44
wenzelm@7410
    45
fun store_thms (name, thms) =
wenzelm@7410
    46
  let val thms' = PureThy.smart_store_thms (name, thms)
wenzelm@7410
    47
  in Present.theorems name thms'; thms' end;
wenzelm@7410
    48
clasohm@1262
    49
wenzelm@4023
    50
(* store on ML toplevel *)
wenzelm@4023
    51
wenzelm@7410
    52
val qed_thms: thm list ref = ref [];
clasohm@1262
    53
wenzelm@4023
    54
val ml_reserved =
wenzelm@4023
    55
 ["abstype", "and", "andalso", "as", "case", "do", "datatype", "else",
wenzelm@4023
    56
  "end", "exception", "fn", "fun", "handle", "if", "in", "infix",
wenzelm@4023
    57
  "infixr", "let", "local", "nonfix", "of", "op", "open", "orelse",
wenzelm@4023
    58
  "raise", "rec", "then", "type", "val", "with", "withtype", "while",
wenzelm@4023
    59
  "eqtype", "functor", "include", "sharing", "sig", "signature",
wenzelm@4023
    60
  "struct", "structure", "where"];
clasohm@1262
    61
wenzelm@4023
    62
fun is_ml_identifier name =
wenzelm@4023
    63
  Syntax.is_identifier name andalso not (name mem ml_reserved);
clasohm@1262
    64
wenzelm@7410
    65
fun warn_ml name =
wenzelm@7410
    66
  if is_ml_identifier name then false
wenzelm@7573
    67
  else if name = "" then true
wenzelm@7410
    68
  else (warning ("Cannot bind theorem(s) " ^ quote name ^ " as ML value"); true);
wenzelm@7410
    69
wenzelm@4023
    70
fun ml_store_thm (name, thm) =
wenzelm@4023
    71
  let val thm' = store_thm (name, thm) in
wenzelm@7410
    72
    if warn_ml name then ()
wenzelm@7410
    73
    else (qed_thms := [thm]; use_text true ("val " ^ name ^ " = hd (! ThmDatabase.qed_thms);"))
wenzelm@7410
    74
  end;
wenzelm@7410
    75
wenzelm@7410
    76
fun ml_store_thms (name, thms) =
wenzelm@7410
    77
  let val thms' = store_thms (name, thms) in
wenzelm@7410
    78
    if warn_ml name then ()
wenzelm@7410
    79
    else (qed_thms := thms; use_text true ("val " ^ name ^ " = ! ThmDatabase.qed_thms;"))
clasohm@1262
    80
  end;
clasohm@1262
    81
wenzelm@4023
    82
fun bind_thm (name, thm) = ml_store_thm (name, standard thm);
wenzelm@7410
    83
fun bind_thms (name, thms) = ml_store_thms (name, map standard thms);
wenzelm@7446
    84
wenzelm@7410
    85
fun qed name = ml_store_thm (name, Goals.result ());
wenzelm@4023
    86
fun qed_goal name thy goal tacsf = ml_store_thm (name, prove_goal thy goal tacsf);
wenzelm@4023
    87
fun qed_goalw name thy rews goal tacsf = ml_store_thm (name, prove_goalw thy rews goal tacsf);
wenzelm@4023
    88
wenzelm@7446
    89
fun no_qed () = ();
wenzelm@7446
    90
wenzelm@4023
    91
wenzelm@4023
    92
wenzelm@4037
    93
(** retrieve theorems **)
clasohm@1132
    94
wenzelm@4037
    95
(*get theorems that contain all of given constants*)
wenzelm@4023
    96
fun thms_containing raw_consts =
wenzelm@4023
    97
  let
wenzelm@4023
    98
    val sign = sign_of_thm (topthm ());
wenzelm@4023
    99
    val consts = map (Sign.intern_const sign) raw_consts;
wenzelm@4023
   100
    val thy = ThyInfo.theory_of_sign sign;
paulson@7182
   101
  in PureThy.thms_containing thy consts end
paulson@7182
   102
  handle THEORY (msg,_) => error msg;
clasohm@1262
   103
clasohm@1132
   104
wenzelm@4023
   105
(*top_const: main constant, ignoring Trueprop*)
wenzelm@4023
   106
fun top_const (_ $ t) = (case head_of t of Const (c, _) => Some c | _ => None)
wenzelm@4023
   107
  | top_const _ = None;
clasohm@1136
   108
nipkow@1221
   109
val intro_const = top_const o concl_of;
nipkow@1221
   110
wenzelm@4023
   111
fun elim_const thm = case prems_of thm of [] => None | p::_ => top_const p;
nipkow@1221
   112
nipkow@1221
   113
(* In case faster access is necessary, the thm db should provide special
nipkow@1221
   114
functions
nipkow@1221
   115
nipkow@1221
   116
index_intros, index_elims: string -> (string * thm) list
nipkow@1221
   117
nipkow@1221
   118
where thm [| A1 ; ...; An |] ==> B is returned by
nipkow@1221
   119
- index_intros c if B  is of the form c t1 ... tn
nipkow@1221
   120
- index_elims c  if A1 is of the form c t1 ... tn
nipkow@1221
   121
*)
nipkow@1221
   122
nipkow@1221
   123
(* could be provided by thm db *)
nipkow@1221
   124
fun index_intros c =
nipkow@1221
   125
  let fun topc(_,thm) = intro_const thm = Some(c);
nipkow@1221
   126
      val named_thms = thms_containing [c]
nipkow@1221
   127
  in filter topc named_thms end;
nipkow@1221
   128
nipkow@1221
   129
(* could be provided by thm db *)
nipkow@1221
   130
fun index_elims c =
nipkow@1221
   131
  let fun topc(_,thm) = elim_const thm = Some(c);
nipkow@1221
   132
      val named_thms = thms_containing [c]
nipkow@1221
   133
  in filter topc named_thms end;
nipkow@1221
   134
nipkow@1221
   135
(*assume that parameters have unique names*)
nipkow@1221
   136
fun goal_params i =
nipkow@1221
   137
  let val gi = getgoal i
nipkow@1221
   138
      val frees = map Free (Logic.strip_params gi)
nipkow@1221
   139
  in (gi,frees) end;
nipkow@1221
   140
nipkow@1221
   141
fun concl_of_goal i =
nipkow@1221
   142
  let val (gi,frees) = goal_params i
nipkow@1221
   143
      val B = Logic.strip_assums_concl gi
nipkow@1221
   144
  in subst_bounds(frees,B) end;
nipkow@1221
   145
nipkow@1221
   146
fun prems_of_goal i =
nipkow@1221
   147
  let val (gi,frees) = goal_params i
nipkow@1221
   148
      val As = Logic.strip_assums_hyp gi
nipkow@1221
   149
  in map (fn A => subst_bounds(frees,A)) As end;
nipkow@1221
   150
paulson@5155
   151
(*returns all those named_thms whose subterm extracted by extract can be
paulson@5155
   152
  instantiated to obj; the list is sorted according to the number of premises
paulson@5155
   153
  and the size of the required substitution.*)
clasohm@1262
   154
fun select_match(obj, signobj, named_thms, extract) =
clasohm@1262
   155
  let fun matches(prop, tsig) =
nipkow@1221
   156
            case extract prop of
nipkow@1221
   157
              None => false
clasohm@1262
   158
            | Some pat => Pattern.matches tsig (pat, obj);
nipkow@1221
   159
berghofe@1654
   160
      fun substsize(prop, tsig) =
berghofe@1654
   161
            let val Some pat = extract prop
berghofe@1654
   162
                val (_,subst) = Pattern.match tsig (pat,obj)
paulson@2150
   163
            in foldl op+
wenzelm@7410
   164
                (0, map (fn (_,t) => size_of_term t) subst)
paulson@2150
   165
            end
berghofe@1654
   166
wenzelm@4546
   167
      fun thm_ord ((p0,s0,_),(p1,s1,_)) =
wenzelm@4546
   168
            prod_ord (int_ord o pairself (fn 0 => 0 | x => 1)) int_ord ((p0,s0),(p1,s1));
berghofe@1654
   169
clasohm@1262
   170
      fun select((p as (_,thm))::named_thms, sels) =
clasohm@1262
   171
            let val {prop, sign, ...} = rep_thm thm
nipkow@1221
   172
            in select(named_thms,
clasohm@1262
   173
                      if Sign.subsig(sign, signobj) andalso
nipkow@1230
   174
                         matches(prop,#tsig(Sign.rep_sg signobj))
berghofe@1654
   175
                      then
wenzelm@7410
   176
                        (nprems_of thm,substsize(prop,#tsig(Sign.rep_sg signobj)),p)::sels
berghofe@1654
   177
                      else sels)
clasohm@1136
   178
            end
clasohm@1136
   179
        | select([],sels) = sels
nipkow@1221
   180
wenzelm@7410
   181
  in map (fn (_,_,t) => t) (sort thm_ord (select(named_thms, []))) end;
nipkow@1221
   182
nipkow@1221
   183
fun find_matching(prop,sign,index,extract) =
nipkow@1221
   184
  (case top_const prop of
nipkow@1221
   185
     Some c => select_match(prop,sign,index c,extract)
nipkow@1221
   186
   | _      => []);
nipkow@1221
   187
nipkow@1221
   188
fun find_intros(prop,sign) =
nipkow@1221
   189
  find_matching(prop,sign,index_intros,Some o Logic.strip_imp_concl);
clasohm@1136
   190
nipkow@1221
   191
fun find_elims sign prop =
nipkow@1221
   192
  let fun major prop = case Logic.strip_imp_prems prop of
nipkow@1221
   193
                         [] => None | p::_ => Some p
nipkow@1221
   194
  in find_matching(prop,sign,index_elims,major) end;
nipkow@1221
   195
nipkow@1221
   196
fun findI i = find_intros(concl_of_goal i,#sign(rep_thm(topthm())));
nipkow@1221
   197
nipkow@1221
   198
fun findEs i =
nipkow@1230
   199
  let fun eq_nth((n1,th1),(n2,th2)) = n1=n2 andalso eq_thm(th1,th2);
nipkow@1230
   200
      val sign = #sign(rep_thm(topthm()))
nipkow@1230
   201
      val thmss = map (find_elims sign) (prems_of_goal i)
nipkow@1230
   202
  in foldl (gen_union eq_nth) ([],thmss) end;
nipkow@1221
   203
nipkow@1221
   204
fun findE i j =
nipkow@1221
   205
  let val sign = #sign(rep_thm(topthm()))
nipkow@1221
   206
  in find_elims sign (nth_elem(j-1, prems_of_goal i)) end;
nipkow@1221
   207
berghofe@3601
   208
clasohm@1132
   209
end;
wenzelm@6204
   210
wenzelm@6204
   211
wenzelm@6204
   212
structure BasicThmDatabase: BASIC_THM_DATABASE = ThmDatabase;
wenzelm@6204
   213
open BasicThmDatabase;