src/Pure/ML/ml_thms.ML
author wenzelm
Sat Nov 04 15:24:40 2017 +0100 (20 months ago)
changeset 67003 49850a679c2c
parent 66067 cdbcb417db67
child 67147 dea94b1aabc3
permissions -rw-r--r--
more robust sorted_entries;
wenzelm@27389
     1
(*  Title:      Pure/ML/ml_thms.ML
wenzelm@27389
     2
    Author:     Makarius
wenzelm@27389
     3
wenzelm@45592
     4
Attribute source and theorem values within ML.
wenzelm@27389
     5
*)
wenzelm@27389
     6
wenzelm@27389
     7
signature ML_THMS =
wenzelm@27389
     8
sig
wenzelm@58011
     9
  val the_attributes: Proof.context -> int -> Token.src list
wenzelm@48782
    10
  val the_thmss: Proof.context -> thm list list
wenzelm@56199
    11
  val get_stored_thms: unit -> thm list
wenzelm@56199
    12
  val get_stored_thm: unit -> thm
wenzelm@56199
    13
  val store_thms: string * thm list -> unit
wenzelm@56199
    14
  val store_thm: string * thm -> unit
wenzelm@56199
    15
  val bind_thm: string * thm -> unit
wenzelm@56199
    16
  val bind_thms: string * thm list -> unit
wenzelm@27389
    17
end;
wenzelm@27389
    18
wenzelm@27389
    19
structure ML_Thms: ML_THMS =
wenzelm@27389
    20
struct
wenzelm@27389
    21
wenzelm@45592
    22
(* auxiliary data *)
wenzelm@27389
    23
wenzelm@48782
    24
type thms = (string * bool) * thm list;  (*name, single, value*)
wenzelm@48782
    25
wenzelm@45592
    26
structure Data = Proof_Data
wenzelm@27389
    27
(
wenzelm@58011
    28
  type T = Token.src list Inttab.table * thms list;
wenzelm@48782
    29
  fun init _ = (Inttab.empty, []);
wenzelm@27389
    30
);
wenzelm@27389
    31
wenzelm@45592
    32
val put_attributes = Data.map o apfst o Inttab.update;
wenzelm@45592
    33
fun the_attributes ctxt name = the (Inttab.lookup (fst (Data.get ctxt)) name);
wenzelm@45592
    34
wenzelm@48782
    35
val get_thmss = snd o Data.get;
wenzelm@48782
    36
val the_thmss = map snd o get_thmss;
wenzelm@48782
    37
val cons_thms = Data.map o apsnd o cons;
wenzelm@45592
    38
wenzelm@45592
    39
wenzelm@45592
    40
(* attribute source *)
wenzelm@27389
    41
wenzelm@53171
    42
val _ = Theory.setup
wenzelm@61814
    43
  (ML_Antiquotation.declaration @{binding attributes} Attrib.attribs
wenzelm@61814
    44
    (fn _ => fn srcs => fn ctxt =>
wenzelm@59112
    45
      let val i = serial () in
wenzelm@59112
    46
        ctxt
wenzelm@61814
    47
        |> put_attributes (i, srcs)
wenzelm@59112
    48
        |> ML_Context.value_decl "attributes"
wenzelm@59112
    49
            ("ML_Thms.the_attributes ML_context " ^ string_of_int i)
wenzelm@59112
    50
      end));
wenzelm@45592
    51
wenzelm@45592
    52
wenzelm@45592
    53
(* fact references *)
wenzelm@27389
    54
wenzelm@56069
    55
fun thm_binding kind is_single thms ctxt =
wenzelm@48782
    56
  let
wenzelm@53169
    57
    val initial = null (get_thmss ctxt);
wenzelm@59112
    58
    val (name, ctxt') = ML_Context.variant kind ctxt;
wenzelm@53169
    59
    val ctxt'' = cons_thms ((name, is_single), thms) ctxt';
wenzelm@27389
    60
wenzelm@59127
    61
    val ml_body = ML_Context.struct_name ctxt ^ "." ^ name;
wenzelm@53169
    62
    fun decl final_ctxt =
wenzelm@48782
    63
      if initial then
wenzelm@48782
    64
        let
wenzelm@53169
    65
          val binds = get_thmss final_ctxt |> map (fn ((a, b), _) => (b ? enclose "[" "]") a);
wenzelm@48782
    66
          val ml_env = "val [" ^ commas binds ^ "] = ML_Thms.the_thmss ML_context;\n";
wenzelm@48782
    67
        in (ml_env, ml_body) end
wenzelm@48782
    68
      else ("", ml_body);
wenzelm@56069
    69
  in (decl, ctxt'') end;
wenzelm@27389
    70
wenzelm@53171
    71
val _ = Theory.setup
wenzelm@56205
    72
  (ML_Antiquotation.declaration @{binding thm} (Attrib.thm >> single) (K (thm_binding "thm" true)) #>
wenzelm@56205
    73
   ML_Antiquotation.declaration @{binding thms} Attrib.thms (K (thm_binding "thms" false)));
wenzelm@27389
    74
wenzelm@27389
    75
wenzelm@27389
    76
(* ad-hoc goals *)
wenzelm@27389
    77
wenzelm@30266
    78
val and_ = Args.$$$ "and";
wenzelm@58866
    79
val by = Parse.reserved "by";
wenzelm@63120
    80
val goal = Scan.unless (by || and_) Args.embedded_inner_syntax;
wenzelm@27389
    81
wenzelm@53171
    82
val _ = Theory.setup
wenzelm@56205
    83
  (ML_Antiquotation.declaration @{binding lemma}
wenzelm@56069
    84
    (Scan.lift (Args.mode "open" -- Parse.enum1 "and" (Scan.repeat1 goal) --
wenzelm@58866
    85
      (Parse.position by -- Method.parse -- Scan.option Method.parse)))
wenzelm@58866
    86
    (fn _ => fn ((is_open, raw_propss), (((_, by_pos), m1), m2)) => fn ctxt =>
wenzelm@56069
    87
      let
wenzelm@66067
    88
        val reports =
wenzelm@66067
    89
          (by_pos, Markup.keyword1 |> Markup.keyword_properties) ::
wenzelm@66067
    90
            maps Method.reports_of (m1 :: the_list m2);
wenzelm@58866
    91
        val _ = Context_Position.reports ctxt reports;
wenzelm@55515
    92
wenzelm@56069
    93
        val propss = burrow (map (rpair []) o Syntax.read_props ctxt) raw_propss;
wenzelm@56069
    94
        val prep_result = Goal.norm_result ctxt #> not is_open ? Thm.close_derivation;
wenzelm@56069
    95
        fun after_qed res goal_ctxt =
wenzelm@56069
    96
          Proof_Context.put_thms false (Auto_Bind.thisN,
wenzelm@56069
    97
            SOME (map prep_result (Proof_Context.export goal_ctxt ctxt (flat res)))) goal_ctxt;
wenzelm@53169
    98
wenzelm@56069
    99
        val ctxt' = ctxt
wenzelm@56069
   100
          |> Proof.theorem NONE after_qed propss
wenzelm@56069
   101
          |> Proof.global_terminal_proof (m1, m2);
wenzelm@56069
   102
        val thms =
wenzelm@56069
   103
          Proof_Context.get_fact ctxt'
wenzelm@56069
   104
            (Facts.named (Proof_Context.full_name ctxt' (Binding.name Auto_Bind.thisN)));
wenzelm@56069
   105
      in thm_binding "lemma" (length (flat propss) = 1) thms ctxt end));
wenzelm@27389
   106
wenzelm@56199
   107
wenzelm@56199
   108
(* old-style theorem bindings *)
wenzelm@56199
   109
wenzelm@56199
   110
structure Stored_Thms = Theory_Data
wenzelm@56199
   111
(
wenzelm@56199
   112
  type T = thm list;
wenzelm@56199
   113
  val empty = [];
wenzelm@56199
   114
  fun extend _ = [];
wenzelm@56199
   115
  fun merge _ = [];
wenzelm@56199
   116
);
wenzelm@56199
   117
wenzelm@62876
   118
fun get_stored_thms () = Stored_Thms.get (Context.the_global_context ());
wenzelm@56199
   119
val get_stored_thm = hd o get_stored_thms;
wenzelm@56199
   120
wenzelm@56199
   121
fun ml_store get (name, ths) =
wenzelm@56199
   122
  let
wenzelm@56199
   123
    val ths' = Context.>>> (Context.map_theory_result
wenzelm@56199
   124
      (Global_Theory.store_thms (Binding.name name, ths)));
wenzelm@56199
   125
    val _ = Theory.setup (Stored_Thms.put ths');
wenzelm@56199
   126
    val _ =
wenzelm@56199
   127
      if name = "" then ()
wenzelm@56199
   128
      else if not (ML_Syntax.is_identifier name) then
wenzelm@56199
   129
        error ("Cannot bind theorem(s) " ^ quote name ^ " as ML value")
wenzelm@56199
   130
      else
wenzelm@56304
   131
        ML_Compiler.eval (ML_Compiler.verbose true ML_Compiler.flags) Position.none
wenzelm@56199
   132
          (ML_Lex.tokenize ("val " ^ name ^ " = " ^ get ^ " ();"));
wenzelm@56199
   133
    val _ = Theory.setup (Stored_Thms.put []);
wenzelm@56199
   134
  in () end;
wenzelm@56199
   135
wenzelm@56199
   136
val store_thms = ml_store "ML_Thms.get_stored_thms";
wenzelm@56199
   137
fun store_thm (name, th) = ml_store "ML_Thms.get_stored_thm" (name, [th]);
wenzelm@56199
   138
wenzelm@56199
   139
fun bind_thm (name, thm) = store_thm (name, Drule.export_without_context thm);
wenzelm@56199
   140
fun bind_thms (name, thms) = store_thms (name, map Drule.export_without_context thms);
wenzelm@56199
   141
wenzelm@27389
   142
end;