src/Pure/global_theory.ML
author wenzelm
Thu Aug 15 16:02:47 2019 +0200 (9 months ago)
changeset 70533 031620901fcd
parent 70494 41108e3e9ca5
child 70543 33749040b6f8
permissions -rw-r--r--
support for (fully reconstructed) proof terms in Scala;
proper cache_typs;
     1 (*  Title:      Pure/global_theory.ML
     2     Author:     Makarius
     3 
     4 Global theory content: stored facts.
     5 *)
     6 
     7 signature GLOBAL_THEORY =
     8 sig
     9   val facts_of: theory -> Facts.T
    10   val check_fact: theory -> xstring * Position.T -> string
    11   val intern_fact: theory -> xstring -> string
    12   val defined_fact: theory -> string -> bool
    13   val alias_fact: binding -> string -> theory -> theory
    14   val hide_fact: bool -> string -> theory -> theory
    15   val get_thms: theory -> xstring -> thm list
    16   val get_thm: theory -> xstring -> thm
    17   val transfer_theories: theory -> thm -> thm
    18   val all_thms_of: theory -> bool -> (string * thm) list
    19   val map_facts: ('a -> 'b) -> ('c * ('a list * 'd) list) list -> ('c * ('b list * 'd) list) list
    20   val burrow_fact: ('a list -> 'b list) -> ('a list * 'c) list -> ('b list * 'c) list
    21   val burrow_facts: ('a list -> 'b list) ->
    22     ('c * ('a list * 'd) list) list -> ('c * ('b list * 'd) list) list
    23   val name_multi: string * Position.T -> 'a list -> ((string * Position.T) * 'a) list
    24   type name_flags
    25   val unnamed: name_flags
    26   val official1: name_flags
    27   val official2: name_flags
    28   val unofficial1: name_flags
    29   val unofficial2: name_flags
    30   val name_thm: name_flags -> string * Position.T -> thm -> thm
    31   val name_thms: name_flags -> string * Position.T -> thm list -> thm list
    32   val check_thms_lazy: thm list lazy -> thm list lazy
    33   val add_thms_lazy: string -> (binding * thm list lazy) -> theory -> theory
    34   val store_thm: binding * thm -> theory -> thm * theory
    35   val store_thm_open: binding * thm -> theory -> thm * theory
    36   val add_thms: ((binding * thm) * attribute list) list -> theory -> thm list * theory
    37   val add_thm: (binding * thm) * attribute list -> theory -> thm * theory
    38   val add_thmss: ((binding * thm list) * attribute list) list -> theory -> thm list list * theory
    39   val add_thms_dynamic': Context.generic -> binding * (Context.generic -> thm list) ->
    40     theory -> string * theory
    41   val add_thms_dynamic: binding * (Context.generic -> thm list) -> theory -> theory
    42   val note_thms: string -> Thm.binding * (thm list * attribute list) list -> theory ->
    43     (string * thm list) * theory
    44   val note_thmss: string -> (Thm.binding * (thm list * attribute list) list) list -> theory ->
    45     (string * thm list) list * theory
    46   val add_defs: bool -> ((binding * term) * attribute list) list ->
    47     theory -> thm list * theory
    48   val add_defs_unchecked: bool -> ((binding * term) * attribute list) list ->
    49     theory -> thm list * theory
    50 end;
    51 
    52 structure Global_Theory: GLOBAL_THEORY =
    53 struct
    54 
    55 (** theory data **)
    56 
    57 structure Data = Theory_Data
    58 (
    59   type T = Facts.T;
    60   val empty = Facts.empty;
    61   val extend = I;
    62   val merge = Facts.merge;
    63 );
    64 
    65 val facts_of = Data.get;
    66 
    67 fun check_fact thy = Facts.check (Context.Theory thy) (facts_of thy);
    68 val intern_fact = Facts.intern o facts_of;
    69 val defined_fact = Facts.defined o facts_of;
    70 
    71 fun alias_fact binding name thy =
    72   Data.map (Facts.alias (Sign.naming_of thy) binding name) thy;
    73 
    74 fun hide_fact fully name = Data.map (Facts.hide fully name);
    75 
    76 
    77 (* retrieve theorems *)
    78 
    79 fun get_thms thy xname =
    80   #thms (Facts.retrieve (Context.Theory thy) (facts_of thy) (xname, Position.none));
    81 
    82 fun get_thm thy xname =
    83   Facts.the_single (xname, Position.none) (get_thms thy xname);
    84 
    85 fun transfer_theories thy =
    86   let
    87     val theories =
    88       fold (fn thy' => Symtab.update (Context.theory_name thy', thy'))
    89         (Theory.nodes_of thy) Symtab.empty;
    90     fun transfer th =
    91       Thm.transfer (the_default thy (Symtab.lookup theories (Thm.theory_name th))) th;
    92   in transfer end;
    93 
    94 fun all_thms_of thy verbose =
    95   let
    96     val transfer = transfer_theories thy;
    97     val facts = facts_of thy;
    98     fun add (name, ths) =
    99       if not verbose andalso Facts.is_concealed facts name then I
   100       else append (map (`(Thm.get_name_hint) o transfer) ths);
   101   in Facts.fold_static add facts [] end;
   102 
   103 
   104 
   105 (** store theorems **)
   106 
   107 (* fact specifications *)
   108 
   109 fun map_facts f = map (apsnd (map (apfst (map f))));
   110 fun burrow_fact f = split_list #>> burrow f #> op ~~;
   111 fun burrow_facts f = split_list ##> burrow (burrow_fact f) #> op ~~;
   112 
   113 
   114 (* name theorems *)
   115 
   116 abstype name_flags = No_Name_Flags | Name_Flags of {pre: bool, official: bool}
   117 with
   118 
   119 val unnamed = No_Name_Flags;
   120 val official1 = Name_Flags {pre = true, official = true};
   121 val official2 = Name_Flags {pre = false, official = true};
   122 val unofficial1 = Name_Flags {pre = true, official = false};
   123 val unofficial2 = Name_Flags {pre = false, official = false};
   124 
   125 fun name_thm name_flags (name, pos) =
   126   Thm.solve_constraints #> (fn thm =>
   127     (case name_flags of
   128       No_Name_Flags => thm
   129     | Name_Flags {pre, official} =>
   130         thm
   131         |> (official andalso (not pre orelse Thm.derivation_name thm = "")) ?
   132             Thm.name_derivation (name, pos)
   133         |> (name <> "" andalso (not pre orelse not (Thm.has_name_hint thm))) ?
   134             Thm.put_name_hint name));
   135 
   136 end;
   137 
   138 fun name_multi (name, pos: Position.T) xs =
   139   (case xs of
   140     [x] => [((name, pos), x)]
   141   | _ =>
   142       if name = "" then map (pair ("", pos)) xs
   143       else map_index (fn (i, x) => ((name ^ "_" ^ string_of_int (i + 1), pos), x)) xs);
   144 
   145 fun name_thms name_flags name_pos thms =
   146   map (uncurry (name_thm name_flags)) (name_multi name_pos thms);
   147 
   148 
   149 (* apply theorems and attributes *)
   150 
   151 fun register_proofs thms thy = (thms, Thm.register_proofs (Lazy.value thms) thy);
   152 
   153 fun bind_name thy b = (Sign.full_name thy b, Binding.default_pos_of b);
   154 
   155 fun add_facts (b, fact) thy =
   156   let
   157     val (full_name, pos) = bind_name thy b;
   158     fun check fact =
   159       fact |> map_index (fn (i, thm) =>
   160         let
   161           fun err msg =
   162             error ("Malformed global fact " ^
   163               quote (full_name ^
   164                 (if length fact = 1 then "" else "(" ^ string_of_int (i + 1) ^ ")")) ^
   165               Position.here pos ^ "\n" ^ msg);
   166           val prop = Thm.plain_prop_of thm
   167             handle THM _ =>
   168               thm
   169               |> Thm.check_hyps (Context.Theory thy)
   170               |> Thm.full_prop_of;
   171         in
   172           ignore (Logic.unvarify_global (Term_Subst.zero_var_indexes prop))
   173             handle TYPE (msg, _, _) => err msg
   174               | TERM (msg, _) => err msg
   175               | ERROR msg => err msg
   176         end);
   177     val arg = (b, Lazy.map_finished (tap check) fact);
   178   in
   179     thy |> Data.map (Facts.add_static (Context.Theory thy) {strict = true, index = false} arg #> #2)
   180   end;
   181 
   182 fun check_thms_lazy (thms: thm list lazy) =
   183   if Proofterm.proofs_enabled () orelse Options.default_bool "strict_facts"
   184   then Lazy.force_value thms else thms;
   185 
   186 fun add_thms_lazy kind (b, thms) thy =
   187   if Binding.is_empty b then Thm.register_proofs (check_thms_lazy thms) thy
   188   else
   189     let
   190       val name_pos = bind_name thy b;
   191       val thms' =
   192         check_thms_lazy thms
   193         |> Lazy.map_finished (name_thms official1 name_pos #> map (Thm.kind_rule kind));
   194     in thy |> Thm.register_proofs thms' |> add_facts (b, thms') end;
   195 
   196 val app_facts =
   197   apfst flat oo fold_map (fn (thms, atts) => fold_map (Thm.theory_attributes atts) thms);
   198 
   199 fun apply_facts name_flags1 name_flags2 (b, facts) thy =
   200   if Binding.is_empty b then app_facts facts thy |-> register_proofs
   201   else
   202     let
   203       val name_pos= bind_name thy b;
   204       val (thms', thy') = thy
   205         |> app_facts (map (apfst (name_thms name_flags1 name_pos)) facts)
   206         |>> name_thms name_flags2 name_pos |-> register_proofs;
   207       val thy'' = thy' |> add_facts (b, Lazy.value thms');
   208     in (map (Thm.transfer thy'') thms', thy'') end;
   209 
   210 
   211 (* store_thm *)
   212 
   213 fun store_thm (b, th) =
   214   apply_facts official1 official2 (b, [([th], [])]) #>> the_single;
   215 
   216 fun store_thm_open (b, th) =
   217   apply_facts unofficial1 unofficial2 (b, [([th], [])]) #>> the_single;
   218 
   219 
   220 (* add_thms(s) *)
   221 
   222 val add_thmss =
   223   fold_map (fn ((b, thms), atts) => apply_facts official1 official2 (b, [(thms, atts)]));
   224 
   225 fun add_thms args =
   226   add_thmss (map (apfst (apsnd single)) args) #>> map the_single;
   227 
   228 val add_thm = yield_singleton add_thms;
   229 
   230 
   231 (* dynamic theorems *)
   232 
   233 fun add_thms_dynamic' context arg thy =
   234   let val (name, facts') = Facts.add_dynamic context arg (Data.get thy)
   235   in (name, Data.put facts' thy) end;
   236 
   237 fun add_thms_dynamic arg thy =
   238   add_thms_dynamic' (Context.Theory thy) arg thy |> snd;
   239 
   240 
   241 (* note_thmss *)
   242 
   243 fun note_thms kind ((b, more_atts), facts) thy =
   244   let
   245     val name = Sign.full_name thy b;
   246     val facts' = facts |> map (apsnd (fn atts => surround (Thm.kind kind) (atts @ more_atts)));
   247     val (thms', thy') = thy |> apply_facts official1 official2 (b, facts');
   248   in ((name, thms'), thy') end;
   249 
   250 val note_thmss = fold_map o note_thms;
   251 
   252 
   253 (* old-style defs *)
   254 
   255 local
   256 
   257 fun add unchecked overloaded = fold_map (fn ((b, prop), atts) => fn thy =>
   258   let
   259     val context = Defs.global_context thy;
   260     val ((_, def), thy') = Thm.add_def context unchecked overloaded (b, prop) thy;
   261     val thm = def
   262       |> Thm.forall_intr_frees
   263       |> Thm.forall_elim_vars 0
   264       |> Thm.varifyT_global;
   265   in thy' |> apply_facts unnamed official2 (b, [([thm], atts)]) |>> the_single end);
   266 
   267 in
   268 
   269 val add_defs = add false;
   270 val add_defs_unchecked = add true;
   271 
   272 end;
   273 
   274 end;