| 74270 |      1 | (*  Title:      Pure/term_items.ML
 | 
|  |      2 |     Author:     Makarius
 | 
|  |      3 | 
 | 
|  |      4 | Scalable collections of term items:
 | 
|  |      5 |   - table: e.g. for instantiation
 | 
|  |      6 |   - set with order of addition, e.g. occurrences within term
 | 
|  |      7 | *)
 | 
|  |      8 | 
 | 
|  |      9 | signature TERM_ITEMS =
 | 
|  |     10 | sig
 | 
|  |     11 |   type key
 | 
|  |     12 |   type 'a table
 | 
|  |     13 |   val empty: 'a table
 | 
|  |     14 |   val build: ('a table -> 'a table) -> 'a table
 | 
|  |     15 |   val size: 'a table -> int
 | 
|  |     16 |   val is_empty: 'a table -> bool
 | 
|  |     17 |   val map: (key -> 'a -> 'b) -> 'a table -> 'b table
 | 
|  |     18 |   val fold: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a
 | 
|  |     19 |   val fold_rev: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a
 | 
|  |     20 |   val dest: 'a table -> (key * 'a) list
 | 
|  |     21 |   val keys: 'a table -> key list
 | 
|  |     22 |   val exists: (key * 'a -> bool) -> 'a table -> bool
 | 
|  |     23 |   val forall: (key * 'a -> bool) -> 'a table -> bool
 | 
|  |     24 |   val get_first: (key * 'a -> 'b option) -> 'a table -> 'b option
 | 
|  |     25 |   val lookup: 'a table -> key -> 'a option
 | 
|  |     26 |   val defined: 'a table -> key -> bool
 | 
|  |     27 |   val add: key * 'a -> 'a table -> 'a table
 | 
|  |     28 |   val make: (key * 'a) list -> 'a table
 | 
|  |     29 |   type set = int table
 | 
|  |     30 |   val add_set: key -> set -> set
 | 
|  |     31 |   val make_set: key list -> set
 | 
|  |     32 |   val list_set: set -> key list
 | 
|  |     33 |   val list_set_rev: set -> key list
 | 
|  |     34 |   val subset: set * set -> bool
 | 
|  |     35 |   val eq_set: set * set -> bool
 | 
|  |     36 | end;
 | 
|  |     37 | 
 | 
|  |     38 | functor Term_Items(Key: KEY): TERM_ITEMS =
 | 
|  |     39 | struct
 | 
|  |     40 | 
 | 
|  |     41 | (* table with length *)
 | 
|  |     42 | 
 | 
|  |     43 | structure Table = Table(Key);
 | 
|  |     44 | 
 | 
|  |     45 | type key = Table.key;
 | 
|  |     46 | datatype 'a table = Items of int * 'a Table.table;
 | 
|  |     47 | 
 | 
|  |     48 | fun size (Items (n, _)) = n;
 | 
|  |     49 | fun table (Items (_, tab)) = tab;
 | 
|  |     50 | 
 | 
|  |     51 | val empty = Items (0, Table.empty);
 | 
|  |     52 | fun build (f: 'a table -> 'a table) = f empty;
 | 
|  |     53 | fun is_empty items = size items = 0;
 | 
|  |     54 | 
 | 
|  |     55 | fun dest items = Table.dest (table items);
 | 
|  |     56 | fun keys items = Table.keys (table items);
 | 
|  |     57 | fun exists pred = Table.exists pred o table;
 | 
|  |     58 | fun forall pred = Table.forall pred o table;
 | 
|  |     59 | fun get_first get = Table.get_first get o table;
 | 
|  |     60 | fun lookup items = Table.lookup (table items);
 | 
|  |     61 | fun defined items = Table.defined (table items);
 | 
|  |     62 | 
 | 
|  |     63 | fun add (key, x) (items as Items (n, tab)) =
 | 
|  |     64 |   if Table.defined tab key then items
 | 
|  |     65 |   else Items (n + 1, Table.update_new (key, x) tab);
 | 
|  |     66 | 
 | 
|  |     67 | fun make entries = build (fold add entries);
 | 
|  |     68 | 
 | 
|  |     69 | 
 | 
|  |     70 | (* set with order of addition *)
 | 
|  |     71 | 
 | 
|  |     72 | type set = int table;
 | 
|  |     73 | 
 | 
|  |     74 | fun add_set x (items as Items (n, tab)) =
 | 
|  |     75 |   if Table.defined tab x then items
 | 
|  |     76 |   else Items (n + 1, Table.update_new (x, n) tab);
 | 
|  |     77 | 
 | 
|  |     78 | fun make_set xs = build (fold add_set xs);
 | 
|  |     79 | 
 | 
|  |     80 | fun subset (A: set, B: set) = forall (defined B o #1) A;
 | 
|  |     81 | fun eq_set (A: set, B: set) = size A = size B andalso subset (A, B);
 | 
|  |     82 | 
 | 
|  |     83 | fun list_set_ord ord items = Table.dest (table items) |> sort (ord o apply2 #2) |> map #1
 | 
|  |     84 | val list_set = list_set_ord int_ord;
 | 
|  |     85 | val list_set_rev = list_set_ord (rev_order o int_ord);
 | 
|  |     86 | 
 | 
|  |     87 | fun map f (Items (n, tab)) = Items (n, Table.map f tab);
 | 
|  |     88 | fun fold f = Table.fold f o table;
 | 
|  |     89 | fun fold_rev f = Table.fold_rev f o table;
 | 
|  |     90 | 
 | 
|  |     91 | end;
 | 
|  |     92 | 
 | 
|  |     93 | 
 | 
|  |     94 | structure TFrees:
 | 
|  |     95 | sig
 | 
|  |     96 |   include TERM_ITEMS
 | 
|  |     97 |   val add_tfreesT: typ -> set -> set
 | 
|  |     98 |   val add_tfrees: term -> set -> set
 | 
| 74278 |     99 |   val add_tfreesT_unless: (string * sort -> bool) -> typ -> set -> set
 | 
|  |    100 |   val add_tfrees_unless: (string * sort -> bool) -> term -> set -> set
 | 
| 74270 |    101 | end =
 | 
|  |    102 | struct
 | 
|  |    103 | 
 | 
|  |    104 | structure Items = Term_Items
 | 
|  |    105 | (
 | 
|  |    106 |   type key = string * sort;
 | 
|  |    107 |   val ord = pointer_eq_ord (prod_ord fast_string_ord Term_Ord.sort_ord);
 | 
|  |    108 | );
 | 
|  |    109 | open Items;
 | 
|  |    110 | 
 | 
|  |    111 | val add_tfreesT = fold_atyps (fn TFree v => add_set v | _ => I);
 | 
|  |    112 | val add_tfrees = fold_types add_tfreesT;
 | 
|  |    113 | 
 | 
| 74278 |    114 | fun add_tfreesT_unless pred = Term.fold_atyps (fn TFree v => not (pred v) ? add_set v | _ => I);
 | 
|  |    115 | fun add_tfrees_unless pred = fold_types (add_tfreesT_unless pred);
 | 
|  |    116 | 
 | 
| 74270 |    117 | end;
 | 
|  |    118 | 
 | 
|  |    119 | 
 | 
|  |    120 | structure TVars:
 | 
|  |    121 | sig
 | 
|  |    122 |   include TERM_ITEMS
 | 
|  |    123 |   val add_tvarsT: typ -> set -> set
 | 
|  |    124 |   val add_tvars: term -> set -> set
 | 
|  |    125 | end =
 | 
|  |    126 | struct
 | 
|  |    127 | 
 | 
|  |    128 | structure Term_Items = Term_Items(
 | 
|  |    129 |   type key = indexname * sort;
 | 
|  |    130 |   val ord = pointer_eq_ord (prod_ord Term_Ord.fast_indexname_ord Term_Ord.sort_ord);
 | 
|  |    131 | );
 | 
|  |    132 | open Term_Items;
 | 
|  |    133 | 
 | 
|  |    134 | val add_tvarsT = fold_atyps (fn TVar v => add_set v | _ => I);
 | 
|  |    135 | val add_tvars = fold_types add_tvarsT;
 | 
|  |    136 | 
 | 
|  |    137 | end;
 | 
|  |    138 | 
 | 
|  |    139 | 
 | 
|  |    140 | structure Frees:
 | 
|  |    141 | sig
 | 
|  |    142 |   include TERM_ITEMS
 | 
|  |    143 |   val add_frees: term -> set -> set
 | 
|  |    144 | end =
 | 
|  |    145 | struct
 | 
|  |    146 | 
 | 
|  |    147 | structure Term_Items = Term_Items
 | 
|  |    148 | (
 | 
|  |    149 |   type key = string * typ;
 | 
|  |    150 |   val ord = pointer_eq_ord (prod_ord fast_string_ord Term_Ord.typ_ord);
 | 
|  |    151 | );
 | 
|  |    152 | open Term_Items;
 | 
|  |    153 | 
 | 
|  |    154 | val add_frees = fold_aterms (fn Free v => add_set v | _ => I);
 | 
|  |    155 | 
 | 
|  |    156 | end;
 | 
|  |    157 | 
 | 
|  |    158 | 
 | 
|  |    159 | structure Vars:
 | 
|  |    160 | sig
 | 
|  |    161 |   include TERM_ITEMS
 | 
|  |    162 |   val add_vars: term -> set -> set
 | 
|  |    163 | end =
 | 
|  |    164 | struct
 | 
|  |    165 | 
 | 
|  |    166 | structure Term_Items = Term_Items
 | 
|  |    167 | (
 | 
|  |    168 |   type key = indexname * typ;
 | 
|  |    169 |   val ord = pointer_eq_ord (prod_ord Term_Ord.fast_indexname_ord Term_Ord.typ_ord)
 | 
|  |    170 | );
 | 
|  |    171 | open Term_Items;
 | 
|  |    172 | 
 | 
|  |    173 | val add_vars = fold_aterms (fn Var v => add_set v | _ => I);
 | 
|  |    174 | 
 | 
|  |    175 | end;
 | 
|  |    176 | 
 | 
|  |    177 | 
 | 
|  |    178 | structure Names:
 | 
|  |    179 | sig
 | 
|  |    180 |   include TERM_ITEMS
 | 
|  |    181 |   val add_tfree_namesT: typ -> set -> set
 | 
|  |    182 |   val add_tfree_names: term -> set -> set
 | 
|  |    183 |   val add_free_names: term -> set -> set
 | 
|  |    184 | end =
 | 
|  |    185 | struct
 | 
|  |    186 | 
 | 
|  |    187 | structure Term_Items = Term_Items
 | 
|  |    188 | (
 | 
|  |    189 |   type key = string;
 | 
|  |    190 |   val ord = fast_string_ord
 | 
|  |    191 | );
 | 
|  |    192 | open Term_Items;
 | 
|  |    193 | 
 | 
|  |    194 | val add_tfree_namesT = fold_atyps (fn TFree (a, _) => add_set a | _ => I);
 | 
|  |    195 | val add_tfree_names = fold_types add_tfree_namesT;
 | 
|  |    196 | val add_free_names = fold_aterms (fn Free (x, _) => add_set x | _ => I);
 | 
|  |    197 | 
 | 
|  |    198 | end;
 |