src/Pure/ML/ml_thms.ML
author Walther Neuper <walther.neuper@jku.at>
Tue, 05 Jan 2021 17:29:39 +0100
changeset 60141 538e96acb633
parent 60140 8bb9b4a2f575
child 60166 7d6f46b7fc10
permissions -rw-r--r--
step 4.7: cannot fill 2 gaps tracing Outer_Syntax .. Output.report

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