| 13270 |      1 | (*  Title:      Pure/fact_index.ML
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Author:     Markus Wenzel, TU Muenchen
 | 
|  |      4 | 
 | 
| 16020 |      5 | Facts indexed by consts or frees.
 | 
| 13270 |      6 | *)
 | 
|  |      7 | 
 | 
|  |      8 | signature FACT_INDEX =
 | 
|  |      9 | sig
 | 
| 16020 |     10 |   type spec
 | 
| 13270 |     11 |   type T
 | 
| 16020 |     12 |   val facts: T -> (string * thm list) list
 | 
| 18026 |     13 |   val could_unify: T -> term -> thm list
 | 
| 13270 |     14 |   val empty: T
 | 
| 18026 |     15 |   val add_global: (string * thm list) -> T -> T
 | 
|  |     16 |   val add_local: (string -> bool) -> (string * thm list) -> T -> T
 | 
| 16020 |     17 |   val find: T -> spec -> (string * thm list) list
 | 
| 13270 |     18 | end;
 | 
|  |     19 | 
 | 
|  |     20 | structure FactIndex: FACT_INDEX =
 | 
|  |     21 | struct
 | 
|  |     22 | 
 | 
| 16020 |     23 | 
 | 
| 13270 |     24 | (* indexing items *)
 | 
|  |     25 | 
 | 
| 18026 |     26 | type spec = string list * string list;
 | 
|  |     27 | 
 | 
| 16874 |     28 | val add_consts = fold_aterms
 | 
|  |     29 |   (fn Const (c, _) => if c = Term.dummy_patternN then I else insert (op =) c | _ => I);
 | 
| 13270 |     30 | 
 | 
| 18026 |     31 | fun add_frees known = fold_aterms
 | 
|  |     32 |   (fn Free (x, _) => if known x then insert (op =) x else I | _ => I);
 | 
| 16874 |     33 | 
 | 
| 18026 |     34 | fun index_term known t (cs, xs) = (add_consts t cs, add_frees known t xs);
 | 
| 13270 |     35 | 
 | 
| 18026 |     36 | fun index_thm known th idx =
 | 
| 16020 |     37 |   let val {tpairs, hyps, prop, ...} = Thm.rep_thm th in
 | 
|  |     38 |     idx
 | 
| 18026 |     39 |     |> index_term known prop
 | 
|  |     40 |     |> fold (index_term known) hyps
 | 
|  |     41 |     |> fold (fn (t, u) => index_term known t #> index_term known u) tpairs
 | 
| 16020 |     42 |   end;
 | 
| 13270 |     43 | 
 | 
|  |     44 | 
 | 
|  |     45 | (* build index *)
 | 
|  |     46 | 
 | 
| 18026 |     47 | type fact = string * thm list;
 | 
|  |     48 | 
 | 
|  |     49 | datatype T = Index of
 | 
|  |     50 |  {facts: fact list,
 | 
|  |     51 |   consts: (serial * fact) list Symtab.table,
 | 
|  |     52 |   frees: (serial * fact) list Symtab.table,
 | 
|  |     53 |   props: thm Net.net};
 | 
| 13270 |     54 | 
 | 
| 16020 |     55 | fun facts (Index {facts, ...}) = facts;
 | 
| 18026 |     56 | fun could_unify (Index {props, ...}) = Net.unify_term props;
 | 
| 16020 |     57 | 
 | 
| 13270 |     58 | val empty =
 | 
| 18026 |     59 |   Index {facts = [], consts = Symtab.empty, frees = Symtab.empty, props = Net.empty};
 | 
| 13270 |     60 | 
 | 
| 18026 |     61 | fun add do_props known (fact as (_, ths)) (Index {facts, consts, frees, props}) =
 | 
| 13270 |     62 |   let
 | 
| 18026 |     63 |     val entry = (serial (), fact);
 | 
|  |     64 |     val (cs, xs) = fold (index_thm known) ths ([], []);
 | 
|  |     65 | 
 | 
|  |     66 |     val facts' = fact :: facts;
 | 
| 18931 |     67 |     val consts' = consts |> fold (fn c => Symtab.update_list (c, entry)) cs;
 | 
|  |     68 |     val frees' = frees |> fold (fn x => Symtab.update_list (x, entry)) xs;
 | 
| 18026 |     69 |     val props' = props |> K do_props ?
 | 
|  |     70 |       fold (fn th => Net.insert_term (K false) (Thm.prop_of th, th)) ths;
 | 
|  |     71 |   in Index {facts = facts', consts = consts', frees = frees', props = props'} end;
 | 
|  |     72 | 
 | 
|  |     73 | val add_global = add false (K false);
 | 
|  |     74 | val add_local = add true;
 | 
| 13270 |     75 | 
 | 
|  |     76 | 
 | 
| 18026 |     77 | (* find by consts/frees *)
 | 
|  |     78 | 
 | 
|  |     79 | local
 | 
| 13270 |     80 | 
 | 
| 16491 |     81 | fun fact_ord ((i, _), (j, _)) = int_ord (j, i);
 | 
| 13270 |     82 | 
 | 
|  |     83 | fun intersects [xs] = xs
 | 
| 16491 |     84 |   | intersects xss =
 | 
|  |     85 |       if exists null xss then []
 | 
|  |     86 |       else fold (OrdList.inter fact_ord) (tl xss) (hd xss);
 | 
| 13270 |     87 | 
 | 
| 18026 |     88 | in
 | 
|  |     89 | 
 | 
| 16020 |     90 | fun find idx ([], []) = facts idx
 | 
|  |     91 |   | find (Index {consts, frees, ...}) (cs, xs) =
 | 
| 18931 |     92 |       (map (Symtab.lookup_list consts) cs @
 | 
|  |     93 |         map (Symtab.lookup_list frees) xs) |> intersects |> map #2;
 | 
| 13270 |     94 | 
 | 
| 18026 |     95 | end
 | 
|  |     96 | 
 | 
| 13270 |     97 | end;
 |