| author | wenzelm | 
| Wed, 13 Jul 2005 16:07:30 +0200 | |
| changeset 16809 | 8ca51a846576 | 
| parent 16793 | 51600bfac176 | 
| child 16863 | 79b9a6481ae4 | 
| permissions | -rw-r--r-- | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1  | 
(* Title: Pure/term.ML  | 
| 0 | 2  | 
ID: $Id$  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
3  | 
Author: Lawrence C Paulson, Cambridge University Computer Laboratory  | 
| 0 | 4  | 
Copyright Cambridge University 1992  | 
| 
1364
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
5  | 
|
| 4444 | 6  | 
Simply typed lambda-calculus: types, terms, and basic operations.  | 
| 0 | 7  | 
*)  | 
8  | 
||
| 
1364
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
9  | 
infix 9 $;  | 
| 
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
10  | 
infixr 5 -->;  | 
| 4444 | 11  | 
infixr --->;  | 
12  | 
infix aconv;  | 
|
| 
1364
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
13  | 
|
| 4444 | 14  | 
signature BASIC_TERM =  | 
15  | 
sig  | 
|
16  | 
type indexname  | 
|
17  | 
type class  | 
|
18  | 
type sort  | 
|
| 
14829
 
cfa5fe01a7b7
moved read_int etc. to library.ML; added type 'arity';
 
wenzelm 
parents: 
14786 
diff
changeset
 | 
19  | 
type arity  | 
| 4444 | 20  | 
datatype typ =  | 
21  | 
Type of string * typ list |  | 
|
22  | 
TFree of string * sort |  | 
|
23  | 
TVar of indexname * sort  | 
|
| 16537 | 24  | 
datatype term =  | 
25  | 
Const of string * typ |  | 
|
26  | 
Free of string * typ |  | 
|
27  | 
Var of indexname * typ |  | 
|
28  | 
Bound of int |  | 
|
29  | 
Abs of string * typ * term |  | 
|
30  | 
op $ of term * term  | 
|
31  | 
exception TYPE of string * typ list * term list  | 
|
32  | 
exception TERM of string * term list  | 
|
| 16710 | 33  | 
val dummyT: typ  | 
34  | 
val no_dummyT: typ -> typ  | 
|
| 4444 | 35  | 
val --> : typ * typ -> typ  | 
36  | 
val ---> : typ list * typ -> typ  | 
|
| 16710 | 37  | 
val dest_Type: typ -> string * typ list  | 
38  | 
val dest_TVar: typ -> indexname * sort  | 
|
39  | 
val dest_TFree: typ -> string * sort  | 
|
40  | 
val is_Bound: term -> bool  | 
|
41  | 
val is_Const: term -> bool  | 
|
42  | 
val is_Free: term -> bool  | 
|
43  | 
val is_Var: term -> bool  | 
|
| 4444 | 44  | 
val is_TVar: typ -> bool  | 
| 15573 | 45  | 
val is_funtype: typ -> bool  | 
| 16710 | 46  | 
val dest_Const: term -> string * typ  | 
47  | 
val dest_Free: term -> string * typ  | 
|
48  | 
val dest_Var: term -> indexname * typ  | 
|
| 4444 | 49  | 
val domain_type: typ -> typ  | 
| 4480 | 50  | 
val range_type: typ -> typ  | 
| 4444 | 51  | 
val binder_types: typ -> typ list  | 
52  | 
val body_type: typ -> typ  | 
|
53  | 
val strip_type: typ -> typ list * typ  | 
|
| 16710 | 54  | 
val type_of1: typ list * term -> typ  | 
| 4444 | 55  | 
val type_of: term -> typ  | 
| 16710 | 56  | 
val fastype_of1: typ list * term -> typ  | 
| 4444 | 57  | 
val fastype_of: term -> typ  | 
| 10806 | 58  | 
val list_abs: (string * typ) list * term -> term  | 
| 4444 | 59  | 
val strip_abs_body: term -> term  | 
60  | 
val strip_abs_vars: term -> (string * typ) list  | 
|
61  | 
val strip_qnt_body: string -> term -> term  | 
|
62  | 
val strip_qnt_vars: string -> term -> (string * typ) list  | 
|
63  | 
val list_comb: term * term list -> term  | 
|
64  | 
val strip_comb: term -> term * term list  | 
|
65  | 
val head_of: term -> term  | 
|
66  | 
val size_of_term: term -> int  | 
|
67  | 
val map_type_tvar: (indexname * sort -> typ) -> typ -> typ  | 
|
68  | 
val map_type_tfree: (string * sort -> typ) -> typ -> typ  | 
|
69  | 
val map_term_types: (typ -> typ) -> term -> term  | 
|
70  | 
val it_term_types: (typ * 'a -> 'a) -> term * 'a -> 'a  | 
|
| 16710 | 71  | 
val aconv: term * term -> bool  | 
72  | 
val aconvs: term list * term list -> bool  | 
|
| 16537 | 73  | 
structure Vartab: TABLE  | 
74  | 
structure Typtab: TABLE  | 
|
75  | 
structure Termtab: TABLE  | 
|
| 4444 | 76  | 
val itselfT: typ -> typ  | 
77  | 
val a_itselfT: typ  | 
|
78  | 
val propT: typ  | 
|
79  | 
val implies: term  | 
|
80  | 
val all: typ -> term  | 
|
81  | 
val equals: typ -> term  | 
|
82  | 
val strip_all_body: term -> term  | 
|
83  | 
val strip_all_vars: term -> (string * typ) list  | 
|
84  | 
val incr_bv: int * int * term -> term  | 
|
85  | 
val incr_boundvars: int -> term -> term  | 
|
86  | 
val add_loose_bnos: term * int * int list -> int list  | 
|
87  | 
val loose_bnos: term -> int list  | 
|
88  | 
val loose_bvar: term * int -> bool  | 
|
89  | 
val loose_bvar1: term * int -> bool  | 
|
90  | 
val subst_bounds: term list * term -> term  | 
|
91  | 
val subst_bound: term * term -> term  | 
|
92  | 
val betapply: term * term -> term  | 
|
93  | 
val eq_ix: indexname * indexname -> bool  | 
|
94  | 
val ins_ix: indexname * indexname list -> indexname list  | 
|
95  | 
val mem_ix: indexname * indexname list -> bool  | 
|
96  | 
val mem_term: term * term list -> bool  | 
|
97  | 
val subset_term: term list * term list -> bool  | 
|
98  | 
val eq_set_term: term list * term list -> bool  | 
|
99  | 
val ins_term: term * term list -> term list  | 
|
100  | 
val union_term: term list * term list -> term list  | 
|
| 5585 | 101  | 
val inter_term: term list * term list -> term list  | 
| 4444 | 102  | 
val could_unify: term * term -> bool  | 
103  | 
val subst_free: (term * term) list -> term -> term  | 
|
104  | 
val xless: (string * int) * indexname -> bool  | 
|
105  | 
val abstract_over: term * term -> term  | 
|
| 11922 | 106  | 
val lambda: term -> term -> term  | 
| 4444 | 107  | 
val absfree: string * typ * term -> term  | 
108  | 
val list_abs_free: (string * typ) list * term -> term  | 
|
109  | 
val list_all_free: (string * typ) list * term -> term  | 
|
110  | 
val list_all: (string * typ) list * term -> term  | 
|
| 16710 | 111  | 
val subst_atomic: (term * term) list -> term -> term  | 
112  | 
val typ_subst_atomic: (typ * typ) list -> typ -> typ  | 
|
113  | 
val subst_atomic_types: (typ * typ) list -> term -> term  | 
|
114  | 
val typ_subst_TVars: (indexname * typ) list -> typ -> typ  | 
|
115  | 
val subst_TVars: (indexname * typ) list -> term -> term  | 
|
116  | 
val subst_Vars: (indexname * term) list -> term -> term  | 
|
117  | 
val subst_vars: (indexname * typ) list * (indexname * term) list -> term -> term  | 
|
118  | 
val is_first_order: string list -> term -> bool  | 
|
| 4444 | 119  | 
val maxidx_of_typ: typ -> int  | 
120  | 
val maxidx_of_typs: typ list -> int  | 
|
121  | 
val maxidx_of_term: term -> int  | 
|
| 16710 | 122  | 
val incr_tvar: int -> typ -> typ  | 
| 4444 | 123  | 
val variant: string list -> string -> string  | 
124  | 
val variantlist: string list * string list -> string list  | 
|
| 16537 | 125  | 
(*note reversed order of args wrt. variant!*)  | 
| 4444 | 126  | 
val add_typ_classes: typ * class list -> class list  | 
127  | 
val add_typ_tycons: typ * string list -> string list  | 
|
128  | 
val add_term_classes: term * class list -> class list  | 
|
| 16710 | 129  | 
val add_term_tycons: term * string list -> string list  | 
| 4444 | 130  | 
val add_term_consts: term * string list -> string list  | 
| 16710 | 131  | 
val add_term_constsT: term * (string * typ) list -> (string * typ) list  | 
| 13646 | 132  | 
val term_consts: term -> string list  | 
| 
16108
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
133  | 
val term_constsT: term -> (string * typ) list  | 
| 16710 | 134  | 
val exists_Const: (string * typ -> bool) -> term -> bool  | 
135  | 
val exists_subterm: (term -> bool) -> term -> bool  | 
|
136  | 
val add_new_id: string list * string -> string list  | 
|
137  | 
val add_term_free_names: term * string list -> string list  | 
|
138  | 
val add_typ_tvars: typ * (indexname * sort) list -> (indexname * sort) list  | 
|
139  | 
val add_typ_tfree_names: typ * string list -> string list  | 
|
140  | 
val add_typ_tfrees: typ * (string * sort) list -> (string * sort) list  | 
|
141  | 
val add_typ_varnames: typ * string list -> string list  | 
|
142  | 
val add_term_tvars: term * (indexname * sort) list -> (indexname * sort) list  | 
|
143  | 
val add_term_tfrees: term * (string * sort) list -> (string * sort) list  | 
|
144  | 
val add_term_tfree_names: term * string list -> string list  | 
|
145  | 
val add_term_tvarnames: term * string list -> string list  | 
|
146  | 
val typ_tfrees: typ -> (string * sort) list  | 
|
147  | 
val typ_tvars: typ -> (indexname * sort) list  | 
|
148  | 
val term_tfrees: term -> (string * sort) list  | 
|
149  | 
val term_tvars: term -> (indexname * sort) list  | 
|
150  | 
val add_typ_ixns: indexname list * typ -> indexname list  | 
|
151  | 
val add_term_tvar_ixns: term * indexname list -> indexname list  | 
|
152  | 
val atless: term * term -> bool  | 
|
153  | 
val insert_aterm: term * term list -> term list  | 
|
154  | 
val add_term_vars: term * term list -> term list  | 
|
155  | 
val term_vars: term -> term list  | 
|
| 4444 | 156  | 
val add_term_frees: term * term list -> term list  | 
157  | 
val term_frees: term -> term list  | 
|
| 16710 | 158  | 
val variant_abs: string * typ * term -> string * term  | 
159  | 
val rename_wrt_term: term -> (string * typ) list -> (string * typ) list  | 
|
| 16787 | 160  | 
val fold_atyps: (typ -> 'a -> 'a) -> typ -> 'a -> 'a  | 
161  | 
val fold_aterms: (term -> 'a -> 'a) -> term -> 'a -> 'a  | 
|
162  | 
val fold_term_types: (term -> typ -> 'a -> 'a) -> term -> 'a -> 'a  | 
|
163  | 
val fold_types: (typ -> 'a -> 'a) -> term -> 'a -> 'a  | 
|
| 16790 | 164  | 
  val foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a
 | 
165  | 
  val foldl_aterms: ('a * term -> 'a) -> 'a * term -> 'a
 | 
|
166  | 
val foldl_term_types: (term -> 'a * typ -> 'a) -> 'a * term -> 'a  | 
|
167  | 
  val foldl_types: ('a * typ -> 'a) -> 'a * term -> 'a
 | 
|
| 4444 | 168  | 
val add_term_names: term * string list -> string list  | 
| 16710 | 169  | 
val add_term_varnames: indexname list * term -> indexname list  | 
170  | 
val term_varnames: term -> indexname list  | 
|
| 4444 | 171  | 
val compress_type: typ -> typ  | 
172  | 
val compress_term: term -> term  | 
|
| 15986 | 173  | 
val show_question_marks: bool ref  | 
| 4444 | 174  | 
end;  | 
| 0 | 175  | 
|
| 4444 | 176  | 
signature TERM =  | 
177  | 
sig  | 
|
178  | 
include BASIC_TERM  | 
|
| 16710 | 179  | 
val argument_type_of: term -> typ  | 
| 16678 | 180  | 
val fast_indexname_ord: indexname * indexname -> order  | 
| 16537 | 181  | 
val indexname_ord: indexname * indexname -> order  | 
182  | 
val sort_ord: sort * sort -> order  | 
|
183  | 
val typ_ord: typ * typ -> order  | 
|
| 16678 | 184  | 
val fast_term_ord: term * term -> order  | 
| 16537 | 185  | 
val term_ord: term * term -> order  | 
186  | 
val hd_ord: term * term -> order  | 
|
187  | 
val termless: term * term -> bool  | 
|
| 16570 | 188  | 
val term_lpo: (string -> int) -> term * term -> order  | 
| 12981 | 189  | 
val match_bvars: (term * term) * (string * string) list -> (string * string) list  | 
190  | 
val rename_abs: term -> term -> term -> term option  | 
|
| 16710 | 191  | 
val maxidx_typ: typ -> int -> int  | 
192  | 
val maxidx_typs: typ list -> int -> int  | 
|
193  | 
val maxidx_term: term -> int -> int  | 
|
| 12499 | 194  | 
val invent_names: string list -> string -> int -> string list  | 
| 16338 | 195  | 
val map_typ: (string -> string) -> (string -> string) -> typ -> typ  | 
196  | 
val map_term: (string -> string) -> (string -> string) -> (string -> string) -> term -> term  | 
|
| 16710 | 197  | 
val dest_abs: string * typ * term -> string * term  | 
| 16790 | 198  | 
(*val add_tvarsT: typ -> (indexname * sort) list -> (indexname * sort) list  | 
| 16787 | 199  | 
val add_tvars: term -> (indexname * sort) list -> (indexname * sort) list  | 
| 12499 | 200  | 
val add_vars: (indexname * typ) list * term -> (indexname * typ) list  | 
| 16790 | 201  | 
val add_frees: (string * typ) list * term -> (string * typ) list*)  | 
202  | 
val add_tvarsT: (indexname * sort) list * typ -> (indexname * sort) list  | 
|
203  | 
val add_tvars: (indexname * sort) list * term -> (indexname * sort) list  | 
|
204  | 
val add_vars: (indexname * typ) list * term -> (indexname * typ) list  | 
|
| 12499 | 205  | 
val add_frees: (string * typ) list * term -> (string * typ) list  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
206  | 
val dummy_patternN: string  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
207  | 
val no_dummy_patterns: term -> term  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
208  | 
val replace_dummy_patterns: int * term -> int * term  | 
| 10552 | 209  | 
val is_replaced_dummy_pattern: indexname -> bool  | 
| 16035 | 210  | 
val show_dummy_patterns: term -> term  | 
| 13484 | 211  | 
val adhoc_freeze_vars: term -> term * string list  | 
| 
14786
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
212  | 
val string_of_vname: indexname -> string  | 
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
213  | 
val string_of_vname': indexname -> string  | 
| 4444 | 214  | 
end;  | 
215  | 
||
216  | 
structure Term: TERM =  | 
|
| 
1364
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
217  | 
struct  | 
| 0 | 218  | 
|
219  | 
(*Indexnames can be quickly renamed by adding an offset to the integer part,  | 
|
220  | 
for resolution.*)  | 
|
| 16537 | 221  | 
type indexname = string * int;  | 
| 0 | 222  | 
|
| 4626 | 223  | 
(* Types are classified by sorts. *)  | 
| 0 | 224  | 
type class = string;  | 
225  | 
type sort = class list;  | 
|
| 
14829
 
cfa5fe01a7b7
moved read_int etc. to library.ML; added type 'arity';
 
wenzelm 
parents: 
14786 
diff
changeset
 | 
226  | 
type arity = string * sort list * sort;  | 
| 0 | 227  | 
|
228  | 
(* The sorts attached to TFrees and TVars specify the sort of that variable *)  | 
|
229  | 
datatype typ = Type of string * typ list  | 
|
230  | 
| TFree of string * sort  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
231  | 
| TVar of indexname * sort;  | 
| 0 | 232  | 
|
| 
6033
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
233  | 
(*Terms. Bound variables are indicated by depth number.  | 
| 0 | 234  | 
Free variables, (scheme) variables and constants have names.  | 
| 4626 | 235  | 
An term is "closed" if every bound variable of level "lev"  | 
| 13000 | 236  | 
is enclosed by at least "lev" abstractions.  | 
| 0 | 237  | 
|
238  | 
It is possible to create meaningless terms containing loose bound vars  | 
|
239  | 
or type mismatches. But such terms are not allowed in rules. *)  | 
|
240  | 
||
| 13000 | 241  | 
datatype term =  | 
| 0 | 242  | 
Const of string * typ  | 
| 13000 | 243  | 
| Free of string * typ  | 
| 0 | 244  | 
| Var of indexname * typ  | 
245  | 
| Bound of int  | 
|
246  | 
| Abs of string*typ*term  | 
|
| 3965 | 247  | 
| op $ of term*term;  | 
| 0 | 248  | 
|
| 16537 | 249  | 
(*Errors involving type mismatches*)  | 
| 0 | 250  | 
exception TYPE of string * typ list * term list;  | 
251  | 
||
| 16537 | 252  | 
(*Errors errors involving terms*)  | 
| 0 | 253  | 
exception TERM of string * term list;  | 
254  | 
||
255  | 
(*Note variable naming conventions!  | 
|
256  | 
a,b,c: string  | 
|
257  | 
f,g,h: functions (including terms of function type)  | 
|
258  | 
i,j,m,n: int  | 
|
259  | 
t,u: term  | 
|
260  | 
v,w: indexnames  | 
|
261  | 
x,y: any  | 
|
262  | 
A,B,C: term (denoting formulae)  | 
|
263  | 
T,U: typ  | 
|
264  | 
*)  | 
|
265  | 
||
266  | 
||
| 
6033
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
267  | 
(** Types **)  | 
| 
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
268  | 
|
| 16537 | 269  | 
(*dummy type for parsing and printing etc.*)  | 
270  | 
val dummyT = Type ("dummy", []);
 | 
|
271  | 
||
272  | 
fun no_dummyT typ =  | 
|
273  | 
let  | 
|
274  | 
    fun check (T as Type ("dummy", _)) =
 | 
|
275  | 
          raise TYPE ("Illegal occurrence of '_' dummy type", [T], [])
 | 
|
276  | 
| check (Type (_, Ts)) = List.app check Ts  | 
|
277  | 
| check _ = ();  | 
|
278  | 
in check typ; typ end;  | 
|
279  | 
||
| 
6033
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
280  | 
fun S --> T = Type("fun",[S,T]);
 | 
| 
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
281  | 
|
| 
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
282  | 
(*handy for multiple args: [T1,...,Tn]--->T gives T1-->(T2--> ... -->T)*)  | 
| 15570 | 283  | 
val op ---> = Library.foldr (op -->);  | 
| 
6033
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
284  | 
|
| 
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
285  | 
fun dest_Type (Type x) = x  | 
| 
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
286  | 
  | dest_Type T = raise TYPE ("dest_Type", [T], []);
 | 
| 15914 | 287  | 
fun dest_TVar (TVar x) = x  | 
288  | 
  | dest_TVar T = raise TYPE ("dest_TVar", [T], []);
 | 
|
289  | 
fun dest_TFree (TFree x) = x  | 
|
290  | 
  | dest_TFree T = raise TYPE ("dest_TFree", [T], []);
 | 
|
| 
6033
 
c8c69a4a7762
moved dest_Type to term.ML from HOL/Tools/primrec_package
 
paulson 
parents: 
5986 
diff
changeset
 | 
291  | 
|
| 16537 | 292  | 
|
| 0 | 293  | 
(** Discriminators **)  | 
294  | 
||
| 7318 | 295  | 
fun is_Bound (Bound _) = true  | 
296  | 
| is_Bound _ = false;  | 
|
297  | 
||
| 0 | 298  | 
fun is_Const (Const _) = true  | 
299  | 
| is_Const _ = false;  | 
|
300  | 
||
301  | 
fun is_Free (Free _) = true  | 
|
302  | 
| is_Free _ = false;  | 
|
303  | 
||
304  | 
fun is_Var (Var _) = true  | 
|
305  | 
| is_Var _ = false;  | 
|
306  | 
||
307  | 
fun is_TVar (TVar _) = true  | 
|
308  | 
| is_TVar _ = false;  | 
|
309  | 
||
| 15573 | 310  | 
(*Differs from proofterm/is_fun in its treatment of TVar*)  | 
311  | 
fun is_funtype (Type("fun",[_,_])) = true
 | 
|
312  | 
| is_funtype _ = false;  | 
|
313  | 
||
| 16537 | 314  | 
|
| 0 | 315  | 
(** Destructors **)  | 
316  | 
||
317  | 
fun dest_Const (Const x) = x  | 
|
318  | 
  | dest_Const t = raise TERM("dest_Const", [t]);
 | 
|
319  | 
||
320  | 
fun dest_Free (Free x) = x  | 
|
321  | 
  | dest_Free t = raise TERM("dest_Free", [t]);
 | 
|
322  | 
||
323  | 
fun dest_Var (Var x) = x  | 
|
324  | 
  | dest_Var t = raise TERM("dest_Var", [t]);
 | 
|
325  | 
||
326  | 
||
| 4464 | 327  | 
fun domain_type (Type("fun", [T,_])) = T
 | 
328  | 
and range_type  (Type("fun", [_,T])) = T;
 | 
|
| 4064 | 329  | 
|
| 0 | 330  | 
(* maps [T1,...,Tn]--->T to the list [T1,T2,...,Tn]*)  | 
331  | 
fun binder_types (Type("fun",[S,T])) = S :: binder_types T
 | 
|
332  | 
| binder_types _ = [];  | 
|
333  | 
||
334  | 
(* maps [T1,...,Tn]--->T to T*)  | 
|
335  | 
fun body_type (Type("fun",[S,T])) = body_type T
 | 
|
336  | 
| body_type T = T;  | 
|
337  | 
||
338  | 
(* maps [T1,...,Tn]--->T to ([T1,T2,...,Tn], T) *)  | 
|
339  | 
fun strip_type T : typ list * typ =  | 
|
340  | 
(binder_types T, body_type T);  | 
|
341  | 
||
342  | 
||
343  | 
(*Compute the type of the term, checking that combinations are well-typed  | 
|
344  | 
Ts = [T0,T1,...] holds types of bound variables 0, 1, ...*)  | 
|
345  | 
fun type_of1 (Ts, Const (_,T)) = T  | 
|
346  | 
| type_of1 (Ts, Free (_,T)) = T  | 
|
| 15570 | 347  | 
| type_of1 (Ts, Bound i) = (List.nth (Ts,i)  | 
348  | 
        handle Subscript => raise TYPE("type_of: bound variable", [], [Bound i]))
 | 
|
| 0 | 349  | 
| type_of1 (Ts, Var (_,T)) = T  | 
350  | 
| type_of1 (Ts, Abs (_,T,body)) = T --> type_of1(T::Ts, body)  | 
|
| 13000 | 351  | 
| type_of1 (Ts, f$u) =  | 
| 0 | 352  | 
let val U = type_of1(Ts,u)  | 
353  | 
and T = type_of1(Ts,f)  | 
|
354  | 
in case T of  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
355  | 
            Type("fun",[T1,T2]) =>
 | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
356  | 
if T1=U then T2 else raise TYPE  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
357  | 
                    ("type_of: type mismatch in application", [T1,U], [f$u])
 | 
| 13000 | 358  | 
| _ => raise TYPE  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
359  | 
                    ("type_of: function type is expected in application",
 | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
360  | 
[T,U], [f$u])  | 
| 0 | 361  | 
end;  | 
362  | 
||
363  | 
fun type_of t : typ = type_of1 ([],t);  | 
|
364  | 
||
365  | 
(*Determines the type of a term, with minimal checking*)  | 
|
| 13000 | 366  | 
fun fastype_of1 (Ts, f$u) =  | 
| 61 | 367  | 
(case fastype_of1 (Ts,f) of  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
368  | 
        Type("fun",[_,T]) => T
 | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
369  | 
        | _ => raise TERM("fastype_of: expected function type", [f$u]))
 | 
| 61 | 370  | 
| fastype_of1 (_, Const (_,T)) = T  | 
371  | 
| fastype_of1 (_, Free (_,T)) = T  | 
|
| 15570 | 372  | 
| fastype_of1 (Ts, Bound i) = (List.nth(Ts,i)  | 
373  | 
         handle Subscript => raise TERM("fastype_of: Bound", [Bound i]))
 | 
|
| 13000 | 374  | 
| fastype_of1 (_, Var (_,T)) = T  | 
| 61 | 375  | 
| fastype_of1 (Ts, Abs (_,T,u)) = T --> fastype_of1 (T::Ts, u);  | 
376  | 
||
377  | 
fun fastype_of t : typ = fastype_of1 ([],t);  | 
|
| 0 | 378  | 
|
| 16678 | 379  | 
(*Determine the argument type of a function*)  | 
380  | 
fun argument_type_of tm =  | 
|
381  | 
let  | 
|
382  | 
    fun argT i (Type ("fun", [T, U])) = if i = 0 then T else argT (i - 1) U
 | 
|
383  | 
      | argT _ T = raise TYPE ("argument_type_of", [T], []);
 | 
|
384  | 
||
385  | 
fun arg 0 _ (Abs (_, T, _)) = T  | 
|
386  | 
| arg i Ts (Abs (_, T, t)) = arg (i - 1) (T :: Ts) t  | 
|
387  | 
| arg i Ts (t $ _) = arg (i + 1) Ts t  | 
|
388  | 
| arg i Ts a = argT i (fastype_of1 (Ts, a));  | 
|
389  | 
in arg 0 [] tm end;  | 
|
390  | 
||
| 0 | 391  | 
|
| 15570 | 392  | 
val list_abs = Library.foldr (fn ((x, T), t) => Abs (x, T, t));  | 
| 10806 | 393  | 
|
| 0 | 394  | 
(* maps (x1,...,xn)t to t *)  | 
| 13000 | 395  | 
fun strip_abs_body (Abs(_,_,t)) = strip_abs_body t  | 
| 0 | 396  | 
| strip_abs_body u = u;  | 
397  | 
||
398  | 
(* maps (x1,...,xn)t to [x1, ..., xn] *)  | 
|
| 13000 | 399  | 
fun strip_abs_vars (Abs(a,T,t)) = (a,T) :: strip_abs_vars t  | 
| 0 | 400  | 
| strip_abs_vars u = [] : (string*typ) list;  | 
401  | 
||
402  | 
||
403  | 
fun strip_qnt_body qnt =  | 
|
404  | 
let fun strip(tm as Const(c,_)$Abs(_,_,t)) = if c=qnt then strip t else tm  | 
|
405  | 
| strip t = t  | 
|
406  | 
in strip end;  | 
|
407  | 
||
408  | 
fun strip_qnt_vars qnt =  | 
|
409  | 
let fun strip(Const(c,_)$Abs(a,T,t)) = if c=qnt then (a,T)::strip t else []  | 
|
410  | 
| strip t = [] : (string*typ) list  | 
|
411  | 
in strip end;  | 
|
412  | 
||
413  | 
||
414  | 
(* maps (f, [t1,...,tn]) to f(t1,...,tn) *)  | 
|
| 15570 | 415  | 
val list_comb : term * term list -> term = Library.foldl (op $);  | 
| 0 | 416  | 
|
417  | 
||
418  | 
(* maps f(t1,...,tn) to (f, [t1,...,tn]) ; naturally tail-recursive*)  | 
|
| 13000 | 419  | 
fun strip_comb u : term * term list =  | 
| 0 | 420  | 
let fun stripc (f$t, ts) = stripc (f, t::ts)  | 
| 13000 | 421  | 
| stripc x = x  | 
| 0 | 422  | 
in stripc(u,[]) end;  | 
423  | 
||
424  | 
||
425  | 
(* maps f(t1,...,tn) to f , which is never a combination *)  | 
|
426  | 
fun head_of (f$t) = head_of f  | 
|
427  | 
| head_of u = u;  | 
|
428  | 
||
429  | 
||
| 16599 | 430  | 
(*number of atoms and abstractions in a term*)  | 
431  | 
fun size_of_term tm =  | 
|
432  | 
let  | 
|
| 16678 | 433  | 
fun add_size (t $ u, n) = add_size (t, add_size (u, n))  | 
434  | 
| add_size (Abs (_ ,_, t), n) = add_size (t, n + 1)  | 
|
435  | 
| add_size (_, n) = n + 1;  | 
|
436  | 
in add_size (tm, 0) end;  | 
|
| 0 | 437  | 
|
| 16678 | 438  | 
fun map_type_tvar f =  | 
439  | 
let  | 
|
440  | 
fun map_aux (Type (a, Ts)) = Type (a, map map_aux Ts)  | 
|
441  | 
| map_aux (TVar x) = f x  | 
|
442  | 
| map_aux T = T;  | 
|
443  | 
in map_aux end;  | 
|
| 
949
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
444  | 
|
| 16678 | 445  | 
fun map_type_tfree f =  | 
446  | 
let  | 
|
447  | 
fun map_aux (Type (a, Ts)) = Type (a, map map_aux Ts)  | 
|
448  | 
| map_aux (TFree x) = f x  | 
|
449  | 
| map_aux T = T;  | 
|
450  | 
in map_aux end;  | 
|
| 
949
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
451  | 
|
| 0 | 452  | 
fun map_term_types f =  | 
| 16678 | 453  | 
let  | 
454  | 
fun map_aux (Const (a, T)) = Const (a, f T)  | 
|
455  | 
| map_aux (Free (a, T)) = Free (a, f T)  | 
|
456  | 
| map_aux (Var (v, T)) = Var (v, f T)  | 
|
457  | 
| map_aux (t as Bound _) = t  | 
|
458  | 
| map_aux (Abs (a, T, t)) = Abs (a, f T, map_aux t)  | 
|
459  | 
| map_aux (t $ u) = map_aux t $ map_aux u;  | 
|
460  | 
in map_aux end;  | 
|
| 0 | 461  | 
|
462  | 
(* iterate a function over all types in a term *)  | 
|
463  | 
fun it_term_types f =  | 
|
464  | 
let fun iter(Const(_,T), a) = f(T,a)  | 
|
465  | 
| iter(Free(_,T), a) = f(T,a)  | 
|
466  | 
| iter(Var(_,T), a) = f(T,a)  | 
|
467  | 
| iter(Abs(_,T,t), a) = iter(t,f(T,a))  | 
|
468  | 
| iter(f$u, a) = iter(f, iter(u, a))  | 
|
469  | 
| iter(Bound _, a) = a  | 
|
470  | 
in iter end  | 
|
471  | 
||
472  | 
||
| 16678 | 473  | 
(** Comparing terms, types, sorts etc. **)  | 
| 16537 | 474  | 
|
| 16678 | 475  | 
(* fast syntactic comparison *)  | 
476  | 
||
477  | 
fun fast_indexname_ord ((x, i), (y, j)) =  | 
|
478  | 
(case int_ord (i, j) of EQUAL => fast_string_ord (x, y) | ord => ord);  | 
|
| 16537 | 479  | 
|
| 16599 | 480  | 
fun sort_ord SS =  | 
481  | 
if pointer_eq SS then EQUAL  | 
|
| 16678 | 482  | 
else list_ord fast_string_ord SS;  | 
483  | 
||
484  | 
local  | 
|
| 16537 | 485  | 
|
| 16678 | 486  | 
fun cons_nr (TVar _) = 0  | 
487  | 
| cons_nr (TFree _) = 1  | 
|
488  | 
| cons_nr (Type _) = 2;  | 
|
| 16537 | 489  | 
|
| 16678 | 490  | 
in  | 
| 16537 | 491  | 
|
492  | 
fun typ_ord TU =  | 
|
493  | 
if pointer_eq TU then EQUAL  | 
|
494  | 
else  | 
|
495  | 
(case TU of  | 
|
| 16678 | 496  | 
(Type (a, Ts), Type (b, Us)) =>  | 
497  | 
(case fast_string_ord (a, b) of EQUAL => list_ord typ_ord (Ts, Us) | ord => ord)  | 
|
498  | 
| (TFree (a, S), TFree (b, S')) =>  | 
|
499  | 
(case fast_string_ord (a, b) of EQUAL => sort_ord (S, S') | ord => ord)  | 
|
500  | 
| (TVar (xi, S), TVar (yj, S')) =>  | 
|
501  | 
(case fast_indexname_ord (xi, yj) of EQUAL => sort_ord (S, S') | ord => ord)  | 
|
502  | 
| (T, U) => int_ord (cons_nr T, cons_nr U));  | 
|
503  | 
||
504  | 
end;  | 
|
505  | 
||
506  | 
local  | 
|
507  | 
||
508  | 
fun cons_nr (Const _) = 0  | 
|
509  | 
| cons_nr (Free _) = 1  | 
|
510  | 
| cons_nr (Var _) = 2  | 
|
511  | 
| cons_nr (Bound _) = 3  | 
|
512  | 
| cons_nr (Abs _) = 4  | 
|
513  | 
| cons_nr (_ $ _) = 5;  | 
|
514  | 
||
515  | 
fun struct_ord (Abs (_, _, t), Abs (_, _, u)) = struct_ord (t, u)  | 
|
516  | 
| struct_ord (t1 $ t2, u1 $ u2) =  | 
|
517  | 
(case struct_ord (t1, u1) of EQUAL => struct_ord (t2, u2) | ord => ord)  | 
|
518  | 
| struct_ord (t, u) = int_ord (cons_nr t, cons_nr u);  | 
|
519  | 
||
520  | 
fun atoms_ord (Abs (_, _, t), Abs (_, _, u)) = atoms_ord (t, u)  | 
|
521  | 
| atoms_ord (t1 $ t2, u1 $ u2) =  | 
|
522  | 
(case atoms_ord (t1, u1) of EQUAL => atoms_ord (t2, u2) | ord => ord)  | 
|
523  | 
| atoms_ord (Const (a, _), Const (b, _)) = fast_string_ord (a, b)  | 
|
524  | 
| atoms_ord (Free (x, _), Free (y, _)) = fast_string_ord (x, y)  | 
|
525  | 
| atoms_ord (Var (xi, _), Var (yj, _)) = fast_indexname_ord (xi, yj)  | 
|
526  | 
| atoms_ord (Bound i, Bound j) = int_ord (i, j)  | 
|
527  | 
| atoms_ord _ = sys_error "atoms_ord";  | 
|
528  | 
||
529  | 
fun types_ord (Abs (_, T, t), Abs (_, U, u)) =  | 
|
530  | 
(case typ_ord (T, U) of EQUAL => types_ord (t, u) | ord => ord)  | 
|
531  | 
| types_ord (t1 $ t2, u1 $ u2) =  | 
|
532  | 
(case types_ord (t1, u1) of EQUAL => types_ord (t2, u2) | ord => ord)  | 
|
533  | 
| types_ord (Const (_, T), Const (_, U)) = typ_ord (T, U)  | 
|
534  | 
| types_ord (Free (_, T), Free (_, U)) = typ_ord (T, U)  | 
|
535  | 
| types_ord (Var (_, T), Var (_, U)) = typ_ord (T, U)  | 
|
536  | 
| types_ord (Bound _, Bound _) = EQUAL  | 
|
537  | 
| types_ord _ = sys_error "types_ord";  | 
|
538  | 
||
539  | 
in  | 
|
540  | 
||
541  | 
fun fast_term_ord tu =  | 
|
542  | 
if pointer_eq tu then EQUAL  | 
|
543  | 
else  | 
|
544  | 
(case struct_ord tu of  | 
|
545  | 
EQUAL => (case atoms_ord tu of EQUAL => types_ord tu | ord => ord)  | 
|
546  | 
| ord => ord);  | 
|
547  | 
||
548  | 
fun op aconv tu = (fast_term_ord tu = EQUAL);  | 
|
549  | 
fun aconvs ts_us = (list_ord fast_term_ord ts_us = EQUAL);  | 
|
550  | 
||
551  | 
structure Vartab = TableFun(type key = indexname val ord = fast_indexname_ord);  | 
|
552  | 
structure Typtab = TableFun(type key = typ val ord = typ_ord);  | 
|
553  | 
structure Termtab = TableFun(type key = term val ord = fast_term_ord);  | 
|
554  | 
||
555  | 
end;  | 
|
| 16537 | 556  | 
|
557  | 
||
558  | 
(* term_ord *)  | 
|
559  | 
||
560  | 
(*a linear well-founded AC-compatible ordering for terms:  | 
|
561  | 
s < t <=> 1. size(s) < size(t) or  | 
|
562  | 
2. size(s) = size(t) and s=f(...) and t=g(...) and f<g or  | 
|
563  | 
3. size(s) = size(t) and s=f(s1..sn) and t=f(t1..tn) and  | 
|
564  | 
(s1..sn) < (t1..tn) (lexicographically)*)  | 
|
| 16678 | 565  | 
|
566  | 
fun indexname_ord ((x, i), (y, j)) =  | 
|
567  | 
(case int_ord (i, j) of EQUAL => string_ord (x, y) | ord => ord);  | 
|
568  | 
||
| 16667 | 569  | 
local  | 
570  | 
||
571  | 
fun hd_depth (t $ _, n) = hd_depth (t, n + 1)  | 
|
572  | 
| hd_depth p = p;  | 
|
| 16537 | 573  | 
|
574  | 
fun dest_hd (Const (a, T)) = (((a, 0), T), 0)  | 
|
575  | 
| dest_hd (Free (a, T)) = (((a, 0), T), 1)  | 
|
576  | 
| dest_hd (Var v) = (v, 2)  | 
|
577  | 
  | dest_hd (Bound i) = ((("", i), dummyT), 3)
 | 
|
578  | 
  | dest_hd (Abs (_, T, _)) = ((("", 0), T), 4);
 | 
|
579  | 
||
| 16667 | 580  | 
in  | 
581  | 
||
| 16537 | 582  | 
fun term_ord tu =  | 
583  | 
if pointer_eq tu then EQUAL  | 
|
584  | 
else  | 
|
585  | 
(case tu of  | 
|
586  | 
(Abs (_, T, t), Abs(_, U, u)) =>  | 
|
587  | 
(case term_ord (t, u) of EQUAL => typ_ord (T, U) | ord => ord)  | 
|
| 16667 | 588  | 
| (t, u) =>  | 
| 16537 | 589  | 
(case int_ord (size_of_term t, size_of_term u) of  | 
590  | 
EQUAL =>  | 
|
591  | 
let  | 
|
| 16667 | 592  | 
val (f, m) = hd_depth (t, 0)  | 
593  | 
and (g, n) = hd_depth (u, 0);  | 
|
594  | 
in  | 
|
595  | 
(case hd_ord (f, g) of EQUAL =>  | 
|
596  | 
(case int_ord (m, n) of EQUAL => args_ord (t, u) | ord => ord)  | 
|
597  | 
| ord => ord)  | 
|
598  | 
end  | 
|
| 16537 | 599  | 
| ord => ord))  | 
600  | 
and hd_ord (f, g) =  | 
|
601  | 
prod_ord (prod_ord indexname_ord typ_ord) int_ord (dest_hd f, dest_hd g)  | 
|
| 16667 | 602  | 
and args_ord (f $ t, g $ u) =  | 
603  | 
(case args_ord (f, g) of EQUAL => term_ord (t, u) | ord => ord)  | 
|
604  | 
| args_ord _ = EQUAL;  | 
|
| 16537 | 605  | 
|
606  | 
fun termless tu = (term_ord tu = LESS);  | 
|
607  | 
||
| 16667 | 608  | 
end;  | 
609  | 
||
610  | 
||
611  | 
(** Lexicographic path order on terms **)  | 
|
612  | 
||
613  | 
(*  | 
|
| 16570 | 614  | 
See Baader & Nipkow, Term rewriting, CUP 1998.  | 
615  | 
Without variables. Const, Var, Bound, Free and Abs are treated all as  | 
|
616  | 
constants.  | 
|
617  | 
||
618  | 
f_ord maps strings to integers and serves two purposes:  | 
|
619  | 
- Predicate on constant symbols. Those that are not recognised by f_ord  | 
|
620  | 
must be mapped to ~1.  | 
|
621  | 
- Order on the recognised symbols. These must be mapped to distinct  | 
|
622  | 
integers >= 0.  | 
|
623  | 
||
| 16667 | 624  | 
*)  | 
| 16570 | 625  | 
|
626  | 
local  | 
|
| 16667 | 627  | 
fun dest_hd f_ord (Const (a, T)) =  | 
| 16570 | 628  | 
let val ord = f_ord a in  | 
629  | 
        if ord = ~1 then ((1, ((a, 0), T)), 0) else ((0, (("", ord), T)), 0)
 | 
|
630  | 
end  | 
|
631  | 
| dest_hd _ (Free (a, T)) = ((1, ((a, 0), T)), 0)  | 
|
632  | 
| dest_hd _ (Var v) = ((1, v), 1)  | 
|
633  | 
  | dest_hd _ (Bound i) = ((1, (("", i), dummyT)), 2)
 | 
|
634  | 
  | dest_hd _ (Abs (_, T, _)) = ((1, (("", 0), T)), 3);
 | 
|
635  | 
||
636  | 
fun term_lpo f_ord (s, t) =  | 
|
637  | 
let val (f, ss) = strip_comb s and (g, ts) = strip_comb t in  | 
|
638  | 
if forall (fn si => term_lpo f_ord (si, t) = LESS) ss  | 
|
639  | 
then case hd_ord f_ord (f, g) of  | 
|
| 16667 | 640  | 
GREATER =>  | 
641  | 
if forall (fn ti => term_lpo f_ord (s, ti) = GREATER) ts  | 
|
642  | 
then GREATER else LESS  | 
|
| 16570 | 643  | 
| EQUAL =>  | 
| 16667 | 644  | 
if forall (fn ti => term_lpo f_ord (s, ti) = GREATER) ts  | 
645  | 
then list_ord (term_lpo f_ord) (ss, ts)  | 
|
646  | 
else LESS  | 
|
| 16570 | 647  | 
| LESS => LESS  | 
648  | 
else GREATER  | 
|
649  | 
end  | 
|
650  | 
and hd_ord f_ord (f, g) = case (f, g) of  | 
|
651  | 
(Abs (_, T, t), Abs (_, U, u)) =>  | 
|
652  | 
(case term_lpo f_ord (t, u) of EQUAL => typ_ord (T, U) | ord => ord)  | 
|
653  | 
| (_, _) => prod_ord (prod_ord int_ord  | 
|
654  | 
(prod_ord indexname_ord typ_ord)) int_ord  | 
|
655  | 
(dest_hd f_ord f, dest_hd f_ord g)  | 
|
656  | 
in  | 
|
657  | 
val term_lpo = term_lpo  | 
|
658  | 
end;  | 
|
659  | 
||
| 16537 | 660  | 
|
| 0 | 661  | 
(** Connectives of higher order logic **)  | 
662  | 
||
| 375 | 663  | 
fun itselfT ty = Type ("itself", [ty]);
 | 
| 14854 | 664  | 
val a_itselfT = itselfT (TFree ("'a", []));
 | 
| 375 | 665  | 
|
| 0 | 666  | 
val propT : typ = Type("prop",[]);
 | 
667  | 
||
668  | 
val implies = Const("==>", propT-->propT-->propT);
 | 
|
669  | 
||
670  | 
fun all T = Const("all", (T-->propT)-->propT);
 | 
|
671  | 
||
672  | 
fun equals T = Const("==", T-->T-->propT);
 | 
|
673  | 
||
674  | 
(* maps !!x1...xn. t to t *)  | 
|
| 13000 | 675  | 
fun strip_all_body (Const("all",_)$Abs(_,_,t))  =  strip_all_body t
 | 
| 0 | 676  | 
| strip_all_body t = t;  | 
677  | 
||
678  | 
(* maps !!x1...xn. t to [x1, ..., xn] *)  | 
|
679  | 
fun strip_all_vars (Const("all",_)$Abs(a,T,t))  =
 | 
|
| 13000 | 680  | 
(a,T) :: strip_all_vars t  | 
| 0 | 681  | 
| strip_all_vars t = [] : (string*typ) list;  | 
682  | 
||
683  | 
(*increments a term's non-local bound variables  | 
|
684  | 
required when moving a term within abstractions  | 
|
685  | 
inc is increment for bound variables  | 
|
686  | 
lev is level at which a bound variable is considered 'loose'*)  | 
|
| 13000 | 687  | 
fun incr_bv (inc, lev, u as Bound i) = if i>=lev then Bound(i+inc) else u  | 
| 0 | 688  | 
| incr_bv (inc, lev, Abs(a,T,body)) =  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
689  | 
Abs(a, T, incr_bv(inc,lev+1,body))  | 
| 13000 | 690  | 
| incr_bv (inc, lev, f$t) =  | 
| 0 | 691  | 
incr_bv(inc,lev,f) $ incr_bv(inc,lev,t)  | 
692  | 
| incr_bv (inc, lev, u) = u;  | 
|
693  | 
||
694  | 
fun incr_boundvars 0 t = t  | 
|
695  | 
| incr_boundvars inc t = incr_bv(inc,0,t);  | 
|
696  | 
||
| 12981 | 697  | 
(*Scan a pair of terms; while they are similar,  | 
698  | 
accumulate corresponding bound vars in "al"*)  | 
|
699  | 
fun match_bvs(Abs(x,_,s),Abs(y,_,t), al) =  | 
|
700  | 
match_bvs(s, t, if x="" orelse y="" then al  | 
|
701  | 
else (x,y)::al)  | 
|
702  | 
| match_bvs(f$s, g$t, al) = match_bvs(f,g,match_bvs(s,t,al))  | 
|
703  | 
| match_bvs(_,_,al) = al;  | 
|
704  | 
||
705  | 
(* strip abstractions created by parameters *)  | 
|
706  | 
fun match_bvars((s,t),al) = match_bvs(strip_abs_body s, strip_abs_body t, al);  | 
|
707  | 
||
708  | 
fun rename_abs pat obj t =  | 
|
709  | 
let  | 
|
710  | 
val ren = match_bvs (pat, obj, []);  | 
|
711  | 
fun ren_abs (Abs (x, T, b)) =  | 
|
| 16678 | 712  | 
Abs (if_none (assoc_string (ren, x)) x, T, ren_abs b)  | 
| 12981 | 713  | 
| ren_abs (f $ t) = ren_abs f $ ren_abs t  | 
714  | 
| ren_abs t = t  | 
|
| 15531 | 715  | 
in if null ren then NONE else SOME (ren_abs t) end;  | 
| 0 | 716  | 
|
717  | 
(*Accumulate all 'loose' bound vars referring to level 'lev' or beyond.  | 
|
718  | 
(Bound 0) is loose at level 0 *)  | 
|
| 13000 | 719  | 
fun add_loose_bnos (Bound i, lev, js) =  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
720  | 
if i<lev then js else (i-lev) ins_int js  | 
| 0 | 721  | 
| add_loose_bnos (Abs (_,_,t), lev, js) = add_loose_bnos (t, lev+1, js)  | 
722  | 
| add_loose_bnos (f$t, lev, js) =  | 
|
| 13000 | 723  | 
add_loose_bnos (f, lev, add_loose_bnos (t, lev, js))  | 
| 0 | 724  | 
| add_loose_bnos (_, _, js) = js;  | 
725  | 
||
726  | 
fun loose_bnos t = add_loose_bnos (t, 0, []);  | 
|
727  | 
||
728  | 
(* loose_bvar(t,k) iff t contains a 'loose' bound variable referring to  | 
|
729  | 
level k or beyond. *)  | 
|
730  | 
fun loose_bvar(Bound i,k) = i >= k  | 
|
731  | 
| loose_bvar(f$t, k) = loose_bvar(f,k) orelse loose_bvar(t,k)  | 
|
732  | 
| loose_bvar(Abs(_,_,t),k) = loose_bvar(t,k+1)  | 
|
733  | 
| loose_bvar _ = false;  | 
|
734  | 
||
| 2792 | 735  | 
fun loose_bvar1(Bound i,k) = i = k  | 
736  | 
| loose_bvar1(f$t, k) = loose_bvar1(f,k) orelse loose_bvar1(t,k)  | 
|
737  | 
| loose_bvar1(Abs(_,_,t),k) = loose_bvar1(t,k+1)  | 
|
738  | 
| loose_bvar1 _ = false;  | 
|
| 0 | 739  | 
|
740  | 
(*Substitute arguments for loose bound variables.  | 
|
741  | 
Beta-reduction of arg(n-1)...arg0 into t replacing (Bound i) with (argi).  | 
|
| 4626 | 742  | 
Note that for ((%x y. c) a b), the bound vars in c are x=1 and y=0  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
743  | 
and the appropriate call is subst_bounds([b,a], c) .  | 
| 0 | 744  | 
Loose bound variables >=n are reduced by "n" to  | 
745  | 
compensate for the disappearance of lambdas.  | 
|
746  | 
*)  | 
|
| 13000 | 747  | 
fun subst_bounds (args: term list, t) : term =  | 
| 0 | 748  | 
let val n = length args;  | 
749  | 
fun subst (t as Bound i, lev) =  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
750  | 
(if i<lev then t (*var is locally bound*)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
751  | 
else incr_boundvars lev (List.nth(args, i-lev))  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
752  | 
handle Subscript => Bound(i-n) (*loose: change it*))  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
753  | 
| subst (Abs(a,T,body), lev) = Abs(a, T, subst(body,lev+1))  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
754  | 
| subst (f$t, lev) = subst(f,lev) $ subst(t,lev)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
755  | 
| subst (t,lev) = t  | 
| 0 | 756  | 
in case args of [] => t | _ => subst (t,0) end;  | 
757  | 
||
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
758  | 
(*Special case: one argument*)  | 
| 13000 | 759  | 
fun subst_bound (arg, t) : term =  | 
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
760  | 
let fun subst (t as Bound i, lev) =  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
761  | 
if i<lev then t (*var is locally bound*)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
762  | 
else if i=lev then incr_boundvars lev arg  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
763  | 
else Bound(i-1) (*loose: change it*)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
764  | 
| subst (Abs(a,T,body), lev) = Abs(a, T, subst(body,lev+1))  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
765  | 
| subst (f$t, lev) = subst(f,lev) $ subst(t,lev)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
766  | 
| subst (t,lev) = t  | 
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
767  | 
in subst (t,0) end;  | 
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
768  | 
|
| 0 | 769  | 
(*beta-reduce if possible, else form application*)  | 
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
770  | 
fun betapply (Abs(_,_,t), u) = subst_bound (u,t)  | 
| 0 | 771  | 
| betapply (f,u) = f$u;  | 
772  | 
||
| 
14786
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
773  | 
|
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
774  | 
(** Equality, membership and insertion of indexnames (string*ints) **)  | 
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
775  | 
|
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
776  | 
(*optimized equality test for indexnames. Yields a huge gain under Poly/ML*)  | 
| 16724 | 777  | 
fun eq_ix ((x, i): indexname, (y, j)) = i = j andalso x = y;  | 
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
778  | 
|
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
779  | 
(*membership in a list, optimized version for indexnames*)  | 
| 2959 | 780  | 
fun mem_ix (_, []) = false  | 
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
781  | 
| mem_ix (x, y :: ys) = eq_ix(x,y) orelse mem_ix (x, ys);  | 
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
782  | 
|
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
783  | 
(*insertion into list, optimized version for indexnames*)  | 
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
784  | 
fun ins_ix (x,xs) = if mem_ix (x, xs) then xs else x :: xs;  | 
| 
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
785  | 
|
| 0 | 786  | 
|
| 2176 | 787  | 
(** Membership, insertion, union for terms **)  | 
788  | 
||
789  | 
fun mem_term (_, []) = false  | 
|
790  | 
| mem_term (t, t'::ts) = t aconv t' orelse mem_term(t,ts);  | 
|
791  | 
||
| 
2182
 
29e56f003599
Removal of polymorphic equality via mem, subset, eq_set, etc
 
paulson 
parents: 
2176 
diff
changeset
 | 
792  | 
fun subset_term ([], ys) = true  | 
| 
 
29e56f003599
Removal of polymorphic equality via mem, subset, eq_set, etc
 
paulson 
parents: 
2176 
diff
changeset
 | 
793  | 
| subset_term (x :: xs, ys) = mem_term (x, ys) andalso subset_term(xs, ys);  | 
| 
 
29e56f003599
Removal of polymorphic equality via mem, subset, eq_set, etc
 
paulson 
parents: 
2176 
diff
changeset
 | 
794  | 
|
| 
 
29e56f003599
Removal of polymorphic equality via mem, subset, eq_set, etc
 
paulson 
parents: 
2176 
diff
changeset
 | 
795  | 
fun eq_set_term (xs, ys) =  | 
| 
 
29e56f003599
Removal of polymorphic equality via mem, subset, eq_set, etc
 
paulson 
parents: 
2176 
diff
changeset
 | 
796  | 
xs = ys orelse (subset_term (xs, ys) andalso subset_term (ys, xs));  | 
| 
 
29e56f003599
Removal of polymorphic equality via mem, subset, eq_set, etc
 
paulson 
parents: 
2176 
diff
changeset
 | 
797  | 
|
| 2176 | 798  | 
fun ins_term(t,ts) = if mem_term(t,ts) then ts else t :: ts;  | 
799  | 
||
800  | 
fun union_term (xs, []) = xs  | 
|
801  | 
| union_term ([], ys) = ys  | 
|
802  | 
| union_term ((x :: xs), ys) = union_term (xs, ins_term (x, ys));  | 
|
803  | 
||
| 5585 | 804  | 
fun inter_term ([], ys) = []  | 
805  | 
| inter_term (x::xs, ys) =  | 
|
806  | 
if mem_term (x,ys) then x :: inter_term(xs,ys) else inter_term(xs,ys);  | 
|
807  | 
||
| 13000 | 808  | 
(*A fast unification filter: true unless the two terms cannot be unified.  | 
| 0 | 809  | 
Terms must be NORMAL. Treats all Vars as distinct. *)  | 
810  | 
fun could_unify (t,u) =  | 
|
811  | 
let fun matchrands (f$t, g$u) = could_unify(t,u) andalso matchrands(f,g)  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
812  | 
| matchrands _ = true  | 
| 0 | 813  | 
in case (head_of t , head_of u) of  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
814  | 
(_, Var _) => true  | 
| 0 | 815  | 
| (Var _, _) => true  | 
816  | 
| (Const(a,_), Const(b,_)) => a=b andalso matchrands(t,u)  | 
|
817  | 
| (Free(a,_), Free(b,_)) => a=b andalso matchrands(t,u)  | 
|
818  | 
| (Bound i, Bound j) => i=j andalso matchrands(t,u)  | 
|
819  | 
| (Abs _, _) => true (*because of possible eta equality*)  | 
|
820  | 
| (_, Abs _) => true  | 
|
821  | 
| _ => false  | 
|
822  | 
end;  | 
|
823  | 
||
824  | 
(*Substitute new for free occurrences of old in a term*)  | 
|
825  | 
fun subst_free [] = (fn t=>t)  | 
|
826  | 
| subst_free pairs =  | 
|
| 13000 | 827  | 
let fun substf u =  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
828  | 
case gen_assoc (op aconv) (pairs, u) of  | 
| 15531 | 829  | 
SOME u' => u'  | 
830  | 
| NONE => (case u of Abs(a,T,t) => Abs(a, T, substf t)  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
831  | 
| t$u' => substf t $ substf u'  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
832  | 
| _ => u)  | 
| 0 | 833  | 
in substf end;  | 
834  | 
||
835  | 
(*a total, irreflexive ordering on index names*)  | 
|
836  | 
fun xless ((a,i), (b,j): indexname) = i<j orelse (i=j andalso a<b);  | 
|
837  | 
||
838  | 
||
| 13000 | 839  | 
(*Abstraction of the term "body" over its occurrences of v,  | 
| 0 | 840  | 
which must contain no loose bound variables.  | 
841  | 
The resulting term is ready to become the body of an Abs.*)  | 
|
842  | 
fun abstract_over (v,body) =  | 
|
843  | 
let fun abst (lev,u) = if (v aconv u) then (Bound lev) else  | 
|
844  | 
(case u of  | 
|
845  | 
Abs(a,T,t) => Abs(a, T, abst(lev+1, t))  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
846  | 
| f$rand => abst(lev,f) $ abst(lev,rand)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
847  | 
| _ => u)  | 
| 0 | 848  | 
in abst(0,body) end;  | 
849  | 
||
| 13665 | 850  | 
fun lambda (v as Free (x, T)) t = Abs (x, T, abstract_over (v, t))  | 
851  | 
| lambda (v as Var ((x, _), T)) t = Abs (x, T, abstract_over (v, t))  | 
|
852  | 
  | lambda v t = raise TERM ("lambda", [v, t]);
 | 
|
| 0 | 853  | 
|
854  | 
(*Form an abstraction over a free variable.*)  | 
|
855  | 
fun absfree (a,T,body) = Abs(a, T, abstract_over (Free(a,T), body));  | 
|
856  | 
||
857  | 
(*Abstraction over a list of free variables*)  | 
|
858  | 
fun list_abs_free ([ ] , t) = t  | 
|
| 13000 | 859  | 
| list_abs_free ((a,T)::vars, t) =  | 
| 0 | 860  | 
absfree(a, T, list_abs_free(vars,t));  | 
861  | 
||
862  | 
(*Quantification over a list of free variables*)  | 
|
863  | 
fun list_all_free ([], t: term) = t  | 
|
| 13000 | 864  | 
| list_all_free ((a,T)::vars, t) =  | 
| 0 | 865  | 
(all T) $ (absfree(a, T, list_all_free(vars,t)));  | 
866  | 
||
867  | 
(*Quantification over a list of variables (already bound in body) *)  | 
|
868  | 
fun list_all ([], t) = t  | 
|
| 13000 | 869  | 
| list_all ((a,T)::vars, t) =  | 
| 0 | 870  | 
(all T) $ (Abs(a, T, list_all(vars,t)));  | 
871  | 
||
| 16678 | 872  | 
(*Replace the ATOMIC term ti by ui; inst = [(t1,u1), ..., (tn,un)].  | 
| 0 | 873  | 
A simultaneous substitution: [ (a,b), (b,a) ] swaps a and b. *)  | 
| 16678 | 874  | 
fun subst_atomic [] tm = tm  | 
875  | 
| subst_atomic inst tm =  | 
|
876  | 
let  | 
|
877  | 
fun subst (Abs (a, T, body)) = Abs (a, T, subst body)  | 
|
878  | 
| subst (t $ u) = subst t $ subst u  | 
|
879  | 
| subst t = if_none (gen_assoc (op aconv) (inst, t)) t;  | 
|
880  | 
in subst tm end;  | 
|
| 0 | 881  | 
|
| 16678 | 882  | 
(*Replace the ATOMIC type Ti by Ui; inst = [(T1,U1), ..., (Tn,Un)].*)  | 
883  | 
fun typ_subst_atomic [] ty = ty  | 
|
884  | 
| typ_subst_atomic inst ty =  | 
|
885  | 
let  | 
|
886  | 
fun subst (Type (a, Ts)) = Type (a, map subst Ts)  | 
|
887  | 
| subst T = if_none (gen_assoc (op = : typ * typ -> bool) (inst, T)) T;  | 
|
888  | 
in subst ty end;  | 
|
| 15797 | 889  | 
|
| 16678 | 890  | 
fun subst_atomic_types [] tm = tm  | 
891  | 
| subst_atomic_types inst tm = map_term_types (typ_subst_atomic inst) tm;  | 
|
892  | 
||
893  | 
fun typ_subst_TVars [] ty = ty  | 
|
894  | 
| typ_subst_TVars inst ty =  | 
|
895  | 
let  | 
|
896  | 
fun subst (Type (a, Ts)) = Type (a, map subst Ts)  | 
|
897  | 
| subst (T as TVar (xi, _)) = if_none (assoc_string_int (inst, xi)) T  | 
|
898  | 
| subst T = T;  | 
|
899  | 
in subst ty end;  | 
|
| 0 | 900  | 
|
| 16678 | 901  | 
fun subst_TVars [] tm = tm  | 
902  | 
| subst_TVars inst tm = map_term_types (typ_subst_TVars inst) tm;  | 
|
| 0 | 903  | 
|
| 16678 | 904  | 
(*see also Envir.norm_term*)  | 
905  | 
fun subst_Vars [] tm = tm  | 
|
906  | 
| subst_Vars inst tm =  | 
|
907  | 
let  | 
|
908  | 
fun subst (t as Var (xi, _)) = if_none (assoc_string_int (inst, xi)) t  | 
|
909  | 
| subst (Abs (a, T, t)) = Abs (a, T, subst t)  | 
|
910  | 
| subst (t $ u) = subst t $ subst u  | 
|
911  | 
| subst t = t;  | 
|
912  | 
in subst tm end;  | 
|
| 0 | 913  | 
|
| 16678 | 914  | 
(*see also Envir.norm_term*)  | 
915  | 
fun subst_vars ([], []) tm = tm  | 
|
916  | 
| subst_vars ([], inst) tm = subst_Vars inst tm  | 
|
917  | 
| subst_vars (instT, inst) tm =  | 
|
918  | 
let  | 
|
919  | 
fun subst (Const (a, T)) = Const (a, typ_subst_TVars instT T)  | 
|
920  | 
| subst (Free (a, T)) = Free (a, typ_subst_TVars instT T)  | 
|
921  | 
| subst (t as Var (xi, T)) =  | 
|
922  | 
(case assoc_string_int (inst, xi) of  | 
|
923  | 
NONE => Var (xi, typ_subst_TVars instT T)  | 
|
924  | 
| SOME t => t)  | 
|
925  | 
| subst (t as Bound _) = t  | 
|
926  | 
| subst (Abs (a, T, t)) = Abs (a, typ_subst_TVars instT T, subst t)  | 
|
927  | 
| subst (t $ u) = subst t $ subst u;  | 
|
928  | 
in subst tm end;  | 
|
| 0 | 929  | 
|
930  | 
||
| 15573 | 931  | 
(** Identifying first-order terms **)  | 
932  | 
||
933  | 
(*Argument Ts is a reverse list of binder types, needed if term t contains Bound vars*)  | 
|
934  | 
fun has_not_funtype Ts t = not (is_funtype (fastype_of1 (Ts,t)));  | 
|
935  | 
||
| 16537 | 936  | 
(*First order means in all terms of the form f(t1,...,tn) no argument has a  | 
| 16589 | 937  | 
function type. The supplied quantifiers are excluded: their argument always  | 
938  | 
has a function type through a recursive call into its body.*)  | 
|
| 16667 | 939  | 
fun is_first_order quants =  | 
| 16589 | 940  | 
let fun first_order1 Ts (Abs (_,T,body)) = first_order1 (T::Ts) body  | 
| 16667 | 941  | 
| first_order1 Ts (Const(q,_) $ Abs(a,T,body)) =  | 
942  | 
q mem_string quants andalso (*it is a known quantifier*)  | 
|
| 16589 | 943  | 
not (is_funtype T) andalso first_order1 (T::Ts) body  | 
| 16667 | 944  | 
| first_order1 Ts t =  | 
945  | 
case strip_comb t of  | 
|
946  | 
(Var _, ts) => forall (first_order1 Ts andf has_not_funtype Ts) ts  | 
|
947  | 
| (Free _, ts) => forall (first_order1 Ts andf has_not_funtype Ts) ts  | 
|
948  | 
| (Const _, ts) => forall (first_order1 Ts andf has_not_funtype Ts) ts  | 
|
949  | 
| (Bound _, ts) => forall (first_order1 Ts andf has_not_funtype Ts) ts  | 
|
950  | 
| (Abs _, ts) => false (*not in beta-normal form*)  | 
|
951  | 
| _ => error "first_order: unexpected case"  | 
|
| 16589 | 952  | 
in first_order1 [] end;  | 
| 15573 | 953  | 
|
| 16710 | 954  | 
|
955  | 
(* maximum index of a typs and terms *)  | 
|
| 0 | 956  | 
|
| 16710 | 957  | 
fun maxidx_typ (TVar ((_, j), _)) i = Int.max (i, j)  | 
958  | 
| maxidx_typ (Type (_, Ts)) i = maxidx_typs Ts i  | 
|
959  | 
| maxidx_typ (TFree _) i = i  | 
|
960  | 
and maxidx_typs [] i = i  | 
|
961  | 
| maxidx_typs (T :: Ts) i = maxidx_typs Ts (maxidx_typ T i);  | 
|
| 0 | 962  | 
|
| 16710 | 963  | 
fun maxidx_term (Var ((_, j), T)) i = maxidx_typ T (Int.max (i, j))  | 
964  | 
| maxidx_term (Const (_, T)) i = maxidx_typ T i  | 
|
965  | 
| maxidx_term (Free (_, T)) i = maxidx_typ T i  | 
|
966  | 
| maxidx_term (Bound _) i = i  | 
|
967  | 
| maxidx_term (Abs (_, T, t)) i = maxidx_term t (maxidx_typ T i)  | 
|
968  | 
| maxidx_term (t $ u) i = maxidx_term u (maxidx_term t i);  | 
|
| 0 | 969  | 
|
| 16710 | 970  | 
fun maxidx_of_typ T = maxidx_typ T ~1;  | 
971  | 
fun maxidx_of_typs Ts = maxidx_typs Ts ~1;  | 
|
972  | 
fun maxidx_of_term t = maxidx_term t ~1;  | 
|
| 13665 | 973  | 
|
| 0 | 974  | 
|
975  | 
(* Increment the index of all Poly's in T by k *)  | 
|
| 16678 | 976  | 
fun incr_tvar 0 T = T  | 
977  | 
| incr_tvar k T = map_type_tvar (fn ((a,i),S) => TVar((a,i+k),S)) T;  | 
|
| 0 | 978  | 
|
979  | 
||
980  | 
(**** Syntax-related declarations ****)  | 
|
981  | 
||
982  | 
(*** Printing ***)  | 
|
983  | 
||
| 14676 | 984  | 
(*Makes a variant of a name distinct from the names in bs.  | 
985  | 
First attaches the suffix and then increments this;  | 
|
| 
12306
 
749a04f0cfb0
variant: preserve suffix of underscores (for skolem/internal names etc.);
 
wenzelm 
parents: 
11922 
diff
changeset
 | 
986  | 
preserves a suffix of underscores "_". *)  | 
| 
 
749a04f0cfb0
variant: preserve suffix of underscores (for skolem/internal names etc.);
 
wenzelm 
parents: 
11922 
diff
changeset
 | 
987  | 
fun variant bs name =  | 
| 
 
749a04f0cfb0
variant: preserve suffix of underscores (for skolem/internal names etc.);
 
wenzelm 
parents: 
11922 
diff
changeset
 | 
988  | 
let  | 
| 
 
749a04f0cfb0
variant: preserve suffix of underscores (for skolem/internal names etc.);
 
wenzelm 
parents: 
11922 
diff
changeset
 | 
989  | 
val (c, u) = pairself implode (Library.take_suffix (equal "_") (Symbol.explode name));  | 
| 12902 | 990  | 
fun vary2 c = if ((c ^ u) mem_string bs) then vary2 (Symbol.bump_string c) else c;  | 
| 14676 | 991  | 
fun vary1 c = if ((c ^ u) mem_string bs) then vary2 (Symbol.bump_init c) else c;  | 
| 
12306
 
749a04f0cfb0
variant: preserve suffix of underscores (for skolem/internal names etc.);
 
wenzelm 
parents: 
11922 
diff
changeset
 | 
992  | 
in vary1 (if c = "" then "u" else c) ^ u end;  | 
| 0 | 993  | 
|
994  | 
(*Create variants of the list of names, with priority to the first ones*)  | 
|
995  | 
fun variantlist ([], used) = []  | 
|
| 13000 | 996  | 
| variantlist(b::bs, used) =  | 
| 0 | 997  | 
let val b' = variant used b  | 
998  | 
in b' :: variantlist (bs, b'::used) end;  | 
|
999  | 
||
| 14695 | 1000  | 
(*Invent fresh names*)  | 
1001  | 
fun invent_names _ _ 0 = []  | 
|
1002  | 
| invent_names used a n =  | 
|
1003  | 
let val b = Symbol.bump_string a in  | 
|
1004  | 
if a mem_string used then invent_names used b n  | 
|
1005  | 
else a :: invent_names used b (n - 1)  | 
|
1006  | 
end;  | 
|
| 11353 | 1007  | 
|
| 16537 | 1008  | 
|
| 
4017
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1009  | 
(** Consts etc. **)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1010  | 
|
| 
15574
 
b1d1b5bfc464
Removed practically all references to Library.foldr.
 
skalberg 
parents: 
15573 
diff
changeset
 | 
1011  | 
fun add_typ_classes (Type (_, Ts), cs) = foldr add_typ_classes cs Ts  | 
| 
4017
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1012  | 
| add_typ_classes (TFree (_, S), cs) = S union cs  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1013  | 
| add_typ_classes (TVar (_, S), cs) = S union cs;  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1014  | 
|
| 16294 | 1015  | 
fun add_typ_tycons (Type (c, Ts), cs) = foldr add_typ_tycons (c ins_string cs) Ts  | 
| 
4017
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1016  | 
| add_typ_tycons (_, cs) = cs;  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1017  | 
|
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1018  | 
val add_term_classes = it_term_types add_typ_classes;  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1019  | 
val add_term_tycons = it_term_types add_typ_tycons;  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1020  | 
|
| 9319 | 1021  | 
fun add_term_consts (Const (c, _), cs) = c ins_string cs  | 
| 
4017
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1022  | 
| add_term_consts (t $ u, cs) = add_term_consts (t, add_term_consts (u, cs))  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1023  | 
| add_term_consts (Abs (_, _, t), cs) = add_term_consts (t, cs)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1024  | 
| add_term_consts (_, cs) = cs;  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1025  | 
|
| 
16108
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1026  | 
fun add_term_constsT (Const c, cs) = c::cs  | 
| 
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1027  | 
| add_term_constsT (t $ u, cs) = add_term_constsT (t, add_term_constsT (u, cs))  | 
| 
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1028  | 
| add_term_constsT (Abs (_, _, t), cs) = add_term_constsT (t, cs)  | 
| 
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1029  | 
| add_term_constsT (_, cs) = cs;  | 
| 
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1030  | 
|
| 13646 | 1031  | 
fun term_consts t = add_term_consts(t,[]);  | 
1032  | 
||
| 
16108
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1033  | 
fun term_constsT t = add_term_constsT(t,[]);  | 
| 
 
cf468b93a02e
Implement cycle-free overloading, so that definitions cannot harm consistency any more (except of course via interaction with axioms).
 
obua 
parents: 
16035 
diff
changeset
 | 
1034  | 
|
| 4185 | 1035  | 
fun exists_Const P t = let  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1036  | 
fun ex (Const c ) = P c  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1037  | 
| ex (t $ u ) = ex t orelse ex u  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1038  | 
| ex (Abs (_, _, t)) = ex t  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1039  | 
| ex _ = false  | 
| 4185 | 1040  | 
in ex t end;  | 
| 
4017
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1041  | 
|
| 4631 | 1042  | 
fun exists_subterm P =  | 
1043  | 
let fun ex t = P t orelse  | 
|
1044  | 
(case t of  | 
|
1045  | 
u $ v => ex u orelse ex v  | 
|
1046  | 
| Abs(_, _, u) => ex u  | 
|
1047  | 
| _ => false)  | 
|
1048  | 
in ex end;  | 
|
1049  | 
||
| 
4017
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1050  | 
(*map classes, tycons*)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1051  | 
fun map_typ f g (Type (c, Ts)) = Type (g c, map (map_typ f g) Ts)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1052  | 
| map_typ f _ (TFree (x, S)) = TFree (x, map f S)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1053  | 
| map_typ f _ (TVar (xi, S)) = TVar (xi, map f S);  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1054  | 
|
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1055  | 
(*map classes, tycons, consts*)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1056  | 
fun map_term f g h (Const (c, T)) = Const (h c, map_typ f g T)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1057  | 
| map_term f g _ (Free (x, T)) = Free (x, map_typ f g T)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1058  | 
| map_term f g _ (Var (xi, T)) = Var (xi, map_typ f g T)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1059  | 
| map_term _ _ _ (t as Bound _) = t  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1060  | 
| map_term f g h (Abs (x, T, t)) = Abs (x, map_typ f g T, map_term f g h t)  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1061  | 
| map_term f g h (t $ u) = map_term f g h t $ map_term f g h u;  | 
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1062  | 
|
| 
 
63878e2587a7
add_typ_classes, add_typ_tycons, add_term_classes, add_term_tycons,
 
wenzelm 
parents: 
3965 
diff
changeset
 | 
1063  | 
|
| 0 | 1064  | 
(** TFrees and TVars **)  | 
1065  | 
||
1066  | 
(*maps (bs,v) to v'::bs this reverses the identifiers bs*)  | 
|
1067  | 
fun add_new_id (bs, c) : string list = variant bs c :: bs;  | 
|
1068  | 
||
| 
12802
 
c69bd9754473
added add_term_free_names (more precise/efficient than add_term_names);
 
wenzelm 
parents: 
12499 
diff
changeset
 | 
1069  | 
(*Accumulates the names of Frees in the term, suppressing duplicates.*)  | 
| 
 
c69bd9754473
added add_term_free_names (more precise/efficient than add_term_names);
 
wenzelm 
parents: 
12499 
diff
changeset
 | 
1070  | 
fun add_term_free_names (Free(a,_), bs) = a ins_string bs  | 
| 
 
c69bd9754473
added add_term_free_names (more precise/efficient than add_term_names);
 
wenzelm 
parents: 
12499 
diff
changeset
 | 
1071  | 
| add_term_free_names (f$u, bs) = add_term_free_names (f, add_term_free_names(u, bs))  | 
| 
 
c69bd9754473
added add_term_free_names (more precise/efficient than add_term_names);
 
wenzelm 
parents: 
12499 
diff
changeset
 | 
1072  | 
| add_term_free_names (Abs(_,_,t), bs) = add_term_free_names(t,bs)  | 
| 
 
c69bd9754473
added add_term_free_names (more precise/efficient than add_term_names);
 
wenzelm 
parents: 
12499 
diff
changeset
 | 
1073  | 
| add_term_free_names (_, bs) = bs;  | 
| 
 
c69bd9754473
added add_term_free_names (more precise/efficient than add_term_names);
 
wenzelm 
parents: 
12499 
diff
changeset
 | 
1074  | 
|
| 0 | 1075  | 
(*Accumulates the names in the term, suppressing duplicates.  | 
1076  | 
Includes Frees and Consts. For choosing unambiguous bound var names.*)  | 
|
| 10666 | 1077  | 
fun add_term_names (Const(a,_), bs) = NameSpace.base a ins_string bs  | 
| 2176 | 1078  | 
| add_term_names (Free(a,_), bs) = a ins_string bs  | 
| 0 | 1079  | 
| add_term_names (f$u, bs) = add_term_names (f, add_term_names(u, bs))  | 
1080  | 
| add_term_names (Abs(_,_,t), bs) = add_term_names(t,bs)  | 
|
1081  | 
| add_term_names (_, bs) = bs;  | 
|
1082  | 
||
1083  | 
(*Accumulates the TVars in a type, suppressing duplicates. *)  | 
|
| 
15574
 
b1d1b5bfc464
Removed practically all references to Library.foldr.
 
skalberg 
parents: 
15573 
diff
changeset
 | 
1084  | 
fun add_typ_tvars(Type(_,Ts),vs) = foldr add_typ_tvars vs Ts  | 
| 0 | 1085  | 
| add_typ_tvars(TFree(_),vs) = vs  | 
| 16294 | 1086  | 
| add_typ_tvars(TVar(v),vs) = insert (op =) v vs;  | 
| 0 | 1087  | 
|
1088  | 
(*Accumulates the TFrees in a type, suppressing duplicates. *)  | 
|
| 
15574
 
b1d1b5bfc464
Removed practically all references to Library.foldr.
 
skalberg 
parents: 
15573 
diff
changeset
 | 
1089  | 
fun add_typ_tfree_names(Type(_,Ts),fs) = foldr add_typ_tfree_names fs Ts  | 
| 2176 | 1090  | 
| add_typ_tfree_names(TFree(f,_),fs) = f ins_string fs  | 
| 0 | 1091  | 
| add_typ_tfree_names(TVar(_),fs) = fs;  | 
1092  | 
||
| 
15574
 
b1d1b5bfc464
Removed practically all references to Library.foldr.
 
skalberg 
parents: 
15573 
diff
changeset
 | 
1093  | 
fun add_typ_tfrees(Type(_,Ts),fs) = foldr add_typ_tfrees fs Ts  | 
| 16294 | 1094  | 
| add_typ_tfrees(TFree(f),fs) = insert (op =) f fs  | 
| 0 | 1095  | 
| add_typ_tfrees(TVar(_),fs) = fs;  | 
1096  | 
||
| 
15574
 
b1d1b5bfc464
Removed practically all references to Library.foldr.
 
skalberg 
parents: 
15573 
diff
changeset
 | 
1097  | 
fun add_typ_varnames(Type(_,Ts),nms) = foldr add_typ_varnames nms Ts  | 
| 2176 | 1098  | 
| add_typ_varnames(TFree(nm,_),nms) = nm ins_string nms  | 
1099  | 
| add_typ_varnames(TVar((nm,_),_),nms) = nm ins_string nms;  | 
|
| 
949
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1100  | 
|
| 0 | 1101  | 
(*Accumulates the TVars in a term, suppressing duplicates. *)  | 
1102  | 
val add_term_tvars = it_term_types add_typ_tvars;  | 
|
1103  | 
||
1104  | 
(*Accumulates the TFrees in a term, suppressing duplicates. *)  | 
|
1105  | 
val add_term_tfrees = it_term_types add_typ_tfrees;  | 
|
1106  | 
val add_term_tfree_names = it_term_types add_typ_tfree_names;  | 
|
1107  | 
||
| 
949
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1108  | 
val add_term_tvarnames = it_term_types add_typ_varnames;  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1109  | 
|
| 0 | 1110  | 
(*Non-list versions*)  | 
1111  | 
fun typ_tfrees T = add_typ_tfrees(T,[]);  | 
|
1112  | 
fun typ_tvars T = add_typ_tvars(T,[]);  | 
|
1113  | 
fun term_tfrees t = add_term_tfrees(t,[]);  | 
|
1114  | 
fun term_tvars t = add_term_tvars(t,[]);  | 
|
1115  | 
||
| 
949
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1116  | 
(*special code to enforce left-to-right collection of TVar-indexnames*)  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1117  | 
|
| 15570 | 1118  | 
fun add_typ_ixns(ixns,Type(_,Ts)) = Library.foldl add_typ_ixns (ixns,Ts)  | 
| 13000 | 1119  | 
| add_typ_ixns(ixns,TVar(ixn,_)) = if mem_ix (ixn, ixns) then ixns  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1120  | 
else ixns@[ixn]  | 
| 
949
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1121  | 
| add_typ_ixns(ixns,TFree(_)) = ixns;  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1122  | 
|
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1123  | 
fun add_term_tvar_ixns(Const(_,T),ixns) = add_typ_ixns(ixns,T)  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1124  | 
| add_term_tvar_ixns(Free(_,T),ixns) = add_typ_ixns(ixns,T)  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1125  | 
| add_term_tvar_ixns(Var(_,T),ixns) = add_typ_ixns(ixns,T)  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1126  | 
| add_term_tvar_ixns(Bound _,ixns) = ixns  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1127  | 
| add_term_tvar_ixns(Abs(_,T,t),ixns) =  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1128  | 
add_term_tvar_ixns(t,add_typ_ixns(ixns,T))  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1129  | 
| add_term_tvar_ixns(f$t,ixns) =  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1130  | 
add_term_tvar_ixns(t,add_term_tvar_ixns(f,ixns));  | 
| 
 
83c588d6fee9
Changed treatment of during type inference internally generated type
 
nipkow 
parents: 
728 
diff
changeset
 | 
1131  | 
|
| 16537 | 1132  | 
|
| 0 | 1133  | 
(** Frees and Vars **)  | 
1134  | 
||
1135  | 
(*a partial ordering (not reflexive) for atomic terms*)  | 
|
1136  | 
fun atless (Const (a,_), Const (b,_)) = a<b  | 
|
1137  | 
| atless (Free (a,_), Free (b,_)) = a<b  | 
|
1138  | 
| atless (Var(v,_), Var(w,_)) = xless(v,w)  | 
|
1139  | 
| atless (Bound i, Bound j) = i<j  | 
|
1140  | 
| atless _ = false;  | 
|
1141  | 
||
1142  | 
(*insert atomic term into partially sorted list, suppressing duplicates (?)*)  | 
|
1143  | 
fun insert_aterm (t,us) =  | 
|
1144  | 
let fun inserta [] = [t]  | 
|
| 13000 | 1145  | 
| inserta (us as u::us') =  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1146  | 
if atless(t,u) then t::us  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1147  | 
else if t=u then us (*duplicate*)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1148  | 
else u :: inserta(us')  | 
| 0 | 1149  | 
in inserta us end;  | 
1150  | 
||
1151  | 
(*Accumulates the Vars in the term, suppressing duplicates*)  | 
|
1152  | 
fun add_term_vars (t, vars: term list) = case t of  | 
|
1153  | 
Var _ => insert_aterm(t,vars)  | 
|
1154  | 
| Abs (_,_,body) => add_term_vars(body,vars)  | 
|
1155  | 
| f$t => add_term_vars (f, add_term_vars(t, vars))  | 
|
1156  | 
| _ => vars;  | 
|
1157  | 
||
1158  | 
fun term_vars t = add_term_vars(t,[]);  | 
|
1159  | 
||
1160  | 
(*Accumulates the Frees in the term, suppressing duplicates*)  | 
|
1161  | 
fun add_term_frees (t, frees: term list) = case t of  | 
|
1162  | 
Free _ => insert_aterm(t,frees)  | 
|
1163  | 
| Abs (_,_,body) => add_term_frees(body,frees)  | 
|
1164  | 
| f$t => add_term_frees (f, add_term_frees(t, frees))  | 
|
1165  | 
| _ => frees;  | 
|
1166  | 
||
1167  | 
fun term_frees t = add_term_frees(t,[]);  | 
|
1168  | 
||
1169  | 
(*Given an abstraction over P, replaces the bound variable by a Free variable  | 
|
| 16678 | 1170  | 
having a unique name*)  | 
| 0 | 1171  | 
fun variant_abs (a,T,P) =  | 
1172  | 
let val b = variant (add_term_names(P,[])) a  | 
|
| 
2192
 
3bf092b5310b
Optimizations: removal of polymorphic equality; one-argument case
 
paulson 
parents: 
2182 
diff
changeset
 | 
1173  | 
in (b, subst_bound (Free(b,T), P)) end;  | 
| 0 | 1174  | 
|
| 16678 | 1175  | 
fun dest_abs (x, T, body) =  | 
1176  | 
let  | 
|
1177  | 
fun name_clash (Free (y, _)) = (x = y)  | 
|
1178  | 
| name_clash (t $ u) = name_clash t orelse name_clash u  | 
|
1179  | 
| name_clash (Abs (_, _, t)) = name_clash t  | 
|
1180  | 
| name_clash _ = false;  | 
|
1181  | 
in  | 
|
1182  | 
if name_clash body then  | 
|
1183  | 
dest_abs (variant [x] x, T, body) (*potentially slow, but rarely happens*)  | 
|
1184  | 
else (x, subst_bound (Free (x, T), body))  | 
|
1185  | 
end;  | 
|
1186  | 
||
| 0 | 1187  | 
(* renames and reverses the strings in vars away from names *)  | 
1188  | 
fun rename_aTs names vars : (string*typ)list =  | 
|
1189  | 
let fun rename_aT (vars,(a,T)) =  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1190  | 
(variant (map #1 vars @ names) a, T) :: vars  | 
| 15570 | 1191  | 
in Library.foldl rename_aT ([],vars) end;  | 
| 0 | 1192  | 
|
1193  | 
fun rename_wrt_term t = rename_aTs (add_term_names(t,[]));  | 
|
| 
1364
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
1194  | 
|
| 1417 | 1195  | 
|
| 
4286
 
a09e3e6da2de
added foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a;
 
wenzelm 
parents: 
4188 
diff
changeset
 | 
1196  | 
(* left-ro-right traversal *)  | 
| 
 
a09e3e6da2de
added foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a;
 
wenzelm 
parents: 
4188 
diff
changeset
 | 
1197  | 
|
| 16790 | 1198  | 
(*fold atoms of type*)  | 
| 16787 | 1199  | 
fun fold_atyps f (Type (_, Ts)) = fold (fold_atyps f) Ts  | 
1200  | 
| fold_atyps f T = f T  | 
|
| 
4286
 
a09e3e6da2de
added foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a;
 
wenzelm 
parents: 
4188 
diff
changeset
 | 
1201  | 
|
| 16790 | 1202  | 
(*fold atoms of term*)  | 
| 16787 | 1203  | 
fun fold_aterms f (t $ u) = (fold_aterms f u) o (fold_aterms f t)  | 
1204  | 
| fold_aterms f (Abs (_, _, t)) = fold_aterms f t  | 
|
1205  | 
| fold_aterms f t = f t;  | 
|
| 
4286
 
a09e3e6da2de
added foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a;
 
wenzelm 
parents: 
4188 
diff
changeset
 | 
1206  | 
|
| 16790 | 1207  | 
(*fold types of term*)  | 
| 16787 | 1208  | 
fun fold_term_types f (t as Const (_, T)) = f t T  | 
1209  | 
| fold_term_types f (t as Free (_, T)) = f t T  | 
|
1210  | 
| fold_term_types f (t as Var (_, T)) = f t T  | 
|
1211  | 
| fold_term_types f (Bound _) = I  | 
|
1212  | 
| fold_term_types f (t as Abs (_, T, b)) = (fold_term_types f b) o (f t T)  | 
|
1213  | 
| fold_term_types f (t $ u) = (fold_term_types f u) o (fold_term_types f t);  | 
|
| 8609 | 1214  | 
|
| 16787 | 1215  | 
fun fold_types f = fold_term_types (fn _ => f);  | 
| 
4286
 
a09e3e6da2de
added foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a;
 
wenzelm 
parents: 
4188 
diff
changeset
 | 
1216  | 
|
| 16790 | 1217  | 
(*foldl atoms of type*)  | 
1218  | 
fun foldl_atyps f (x, Type (_, Ts)) = Library.foldl (foldl_atyps f) (x, Ts)  | 
|
1219  | 
| foldl_atyps f x_atom = f x_atom;  | 
|
1220  | 
||
1221  | 
(*foldl atoms of term*)  | 
|
1222  | 
fun foldl_aterms f (x, t $ u) = foldl_aterms f (foldl_aterms f (x, t), u)  | 
|
1223  | 
| foldl_aterms f (x, Abs (_, _, t)) = foldl_aterms f (x, t)  | 
|
1224  | 
| foldl_aterms f x_atom = f x_atom;  | 
|
1225  | 
||
1226  | 
(*foldl types of term*)  | 
|
1227  | 
fun foldl_term_types f (x, t as Const (_, T)) = f t (x, T)  | 
|
1228  | 
| foldl_term_types f (x, t as Free (_, T)) = f t (x, T)  | 
|
1229  | 
| foldl_term_types f (x, t as Var (_, T)) = f t (x, T)  | 
|
1230  | 
| foldl_term_types f (x, Bound _) = x  | 
|
1231  | 
| foldl_term_types f (x, t as Abs (_, T, b)) = foldl_term_types f (f t (x, T), b)  | 
|
1232  | 
| foldl_term_types f (x, t $ u) = foldl_term_types f (foldl_term_types f (x, t), u);  | 
|
1233  | 
||
1234  | 
fun foldl_types f = foldl_term_types (fn _ => f);  | 
|
1235  | 
||
1236  | 
(*(*collect variables*)  | 
|
| 16787 | 1237  | 
val add_tvarsT =  | 
1238  | 
let fun add_tvarsT' (TVar v) = insert (op =) v  | 
|
1239  | 
| add_tvarsT' _ = I  | 
|
1240  | 
in fold_atyps add_tvarsT' end;  | 
|
1241  | 
val add_tvars = fold_types add_tvarsT;  | 
|
1242  | 
val add_vars =  | 
|
1243  | 
let fun add_vars' (Var v) = insert (op =) v  | 
|
1244  | 
| add_vars' _ = I  | 
|
1245  | 
in uncurry (fold_aterms add_vars') o swap end;  | 
|
1246  | 
val add_frees =  | 
|
1247  | 
let fun add_frees' (Free v) = insert (op =) v  | 
|
1248  | 
| add_frees' _ = I  | 
|
| 16793 | 1249  | 
in uncurry (fold_aterms add_frees') o swap end;  | 
| 12499 | 1250  | 
|
| 15025 | 1251  | 
(*collect variable names*)  | 
| 16787 | 1252  | 
val add_term_varnames =  | 
1253  | 
let fun add_term_varnames' (Var (x, _)) xs = ins_ix (x, xs)  | 
|
1254  | 
| add_term_varnames' _ xs = xs  | 
|
1255  | 
in uncurry (fold_aterms add_term_varnames') o swap end;  | 
|
1256  | 
||
| 16790 | 1257  | 
fun term_varnames t = add_term_varnames ([], t);*)  | 
1258  | 
||
1259  | 
(*collect variables*)  | 
|
1260  | 
val add_tvarsT = foldl_atyps (fn (vs, TVar v) => insert (op =) v vs | (vs, _) => vs);  | 
|
1261  | 
val add_tvars = foldl_types add_tvarsT;  | 
|
1262  | 
val add_vars = foldl_aterms (fn (vs, Var v) => insert (op =) v vs | (vs, _) => vs);  | 
|
1263  | 
val add_frees = foldl_aterms (fn (vs, Free v) => insert (op =) v vs | (vs, _) => vs);  | 
|
1264  | 
||
1265  | 
(*collect variable names*)  | 
|
1266  | 
val add_term_varnames = foldl_aterms (fn (xs, Var (x, _)) => ins_ix (x, xs) | (xs, _) => xs);  | 
|
| 15025 | 1267  | 
fun term_varnames t = add_term_varnames ([], t);  | 
| 
4286
 
a09e3e6da2de
added foldl_atyps: ('a * typ -> 'a) -> 'a * typ -> 'a;
 
wenzelm 
parents: 
4188 
diff
changeset
 | 
1268  | 
|
| 1417 | 1269  | 
|
| 4444 | 1270  | 
|
| 13000 | 1271  | 
(*** Compression of terms and types by sharing common subtrees.  | 
1272  | 
Saves 50-75% on storage requirements. As it is a bit slow,  | 
|
1273  | 
it should be called only for axioms, stored theorems, etc.  | 
|
1274  | 
Recorded term and type fragments are never disposed. ***)  | 
|
| 1417 | 1275  | 
|
| 16338 | 1276  | 
|
| 1417 | 1277  | 
(** Sharing of types **)  | 
1278  | 
||
| 13000 | 1279  | 
val memo_types = ref (Typtab.empty: typ Typtab.table);  | 
| 1417 | 1280  | 
|
1281  | 
fun compress_type T =  | 
|
| 13000 | 1282  | 
(case Typtab.lookup (! memo_types, T) of  | 
| 15531 | 1283  | 
SOME T' => T'  | 
1284  | 
| NONE =>  | 
|
| 13000 | 1285  | 
let val T' = (case T of Type (a, Ts) => Type (a, map compress_type Ts) | _ => T)  | 
1286  | 
in memo_types := Typtab.update ((T', T'), ! memo_types); T' end);  | 
|
1287  | 
||
| 1417 | 1288  | 
|
1289  | 
(** Sharing of atomic terms **)  | 
|
1290  | 
||
| 13000 | 1291  | 
val memo_terms = ref (Termtab.empty : term Termtab.table);  | 
| 1417 | 1292  | 
|
1293  | 
fun share_term (t $ u) = share_term t $ share_term u  | 
|
| 13000 | 1294  | 
| share_term (Abs (a, T, u)) = Abs (a, T, share_term u)  | 
| 1417 | 1295  | 
| share_term t =  | 
| 13000 | 1296  | 
(case Termtab.lookup (! memo_terms, t) of  | 
| 15531 | 1297  | 
SOME t' => t'  | 
1298  | 
| NONE => (memo_terms := Termtab.update ((t, t), ! memo_terms); t));  | 
|
| 1417 | 1299  | 
|
1300  | 
val compress_term = share_term o map_term_types compress_type;  | 
|
1301  | 
||
| 4444 | 1302  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1303  | 
(* dummy patterns *)  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1304  | 
|
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1305  | 
val dummy_patternN = "dummy_pattern";  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1306  | 
|
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1307  | 
fun is_dummy_pattern (Const ("dummy_pattern", _)) = true
 | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1308  | 
| is_dummy_pattern _ = false;  | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1309  | 
|
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1310  | 
fun no_dummy_patterns tm =  | 
| 16787 | 1311  | 
if not (fold_aterms (fn t => fn b => b orelse is_dummy_pattern t) tm false) then tm  | 
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1312  | 
  else raise TERM ("Illegal occurrence of '_' dummy pattern", [tm]);
 | 
| 
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1313  | 
|
| 11903 | 1314  | 
fun replace_dummy Ts (i, Const ("dummy_pattern", T)) =
 | 
1315  | 
      (i + 1, list_comb (Var (("_dummy_", i), Ts ---> T), map Bound (0 upto length Ts - 1)))
 | 
|
1316  | 
| replace_dummy Ts (i, Abs (x, T, t)) =  | 
|
1317  | 
let val (i', t') = replace_dummy (T :: Ts) (i, t)  | 
|
1318  | 
in (i', Abs (x, T, t')) end  | 
|
1319  | 
| replace_dummy Ts (i, t $ u) =  | 
|
1320  | 
let val (i', t') = replace_dummy Ts (i, t); val (i'', u') = replace_dummy Ts (i', u)  | 
|
1321  | 
in (i'', t' $ u') end  | 
|
1322  | 
| replace_dummy _ (i, a) = (i, a);  | 
|
1323  | 
||
1324  | 
val replace_dummy_patterns = replace_dummy [];  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1325  | 
|
| 10552 | 1326  | 
fun is_replaced_dummy_pattern ("_dummy_", _) = true
 | 
1327  | 
| is_replaced_dummy_pattern _ = false;  | 
|
| 
9536
 
b79b002f32ae
added dummy_patternN, no_dummy_patterns, replace_dummy_patterns;
 
wenzelm 
parents: 
9319 
diff
changeset
 | 
1328  | 
|
| 16035 | 1329  | 
fun show_dummy_patterns (Var (("_dummy_", _), T)) = Const ("dummy_pattern", T)
 | 
1330  | 
| show_dummy_patterns (t $ u) = show_dummy_patterns t $ show_dummy_patterns u  | 
|
1331  | 
| show_dummy_patterns (Abs (x, T, t)) = Abs (x, T, show_dummy_patterns t)  | 
|
1332  | 
| show_dummy_patterns a = a;  | 
|
1333  | 
||
| 13484 | 1334  | 
|
1335  | 
(* adhoc freezing *)  | 
|
1336  | 
||
1337  | 
fun adhoc_freeze_vars tm =  | 
|
1338  | 
let  | 
|
1339  | 
fun mk_inst (var as Var ((a, i), T)) =  | 
|
1340  | 
let val x = a ^ Library.gensym "_" ^ string_of_int i  | 
|
1341  | 
in ((var, Free(x, T)), x) end;  | 
|
1342  | 
val (insts, xs) = split_list (map mk_inst (term_vars tm));  | 
|
1343  | 
in (subst_atomic insts tm, xs) end;  | 
|
1344  | 
||
1345  | 
||
| 
14786
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1346  | 
(* string_of_vname *)  | 
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1347  | 
|
| 15986 | 1348  | 
val show_question_marks = ref true;  | 
| 15472 | 1349  | 
|
| 
14786
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1350  | 
fun string_of_vname (x, i) =  | 
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1351  | 
let  | 
| 15986 | 1352  | 
val question_mark = if ! show_question_marks then "?" else "";  | 
1353  | 
val idx = string_of_int i;  | 
|
1354  | 
val dot =  | 
|
1355  | 
(case rev (Symbol.explode x) of  | 
|
1356  | 
_ :: "\\<^isub>" :: _ => false  | 
|
1357  | 
| _ :: "\\<^isup>" :: _ => false  | 
|
1358  | 
| c :: _ => Symbol.is_digit c  | 
|
1359  | 
| _ => true);  | 
|
| 
14786
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1360  | 
in  | 
| 15986 | 1361  | 
if dot then question_mark ^ x ^ "." ^ idx  | 
1362  | 
else if i <> 0 then question_mark ^ x ^ idx  | 
|
1363  | 
else question_mark ^ x  | 
|
| 
14786
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1364  | 
end;  | 
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1365  | 
|
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1366  | 
fun string_of_vname' (x, ~1) = x  | 
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1367  | 
| string_of_vname' xi = string_of_vname xi;  | 
| 
 
24a7bc97a27a
moved some sort ops to sorts.ML; added string_of_vname (from Syntax module);
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
1368  | 
|
| 
1364
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
1369  | 
end;  | 
| 
 
8ea1a962ad72
files now define a structure to allow SML/NJ to optimize the code
 
clasohm 
parents: 
1029 
diff
changeset
 | 
1370  | 
|
| 4444 | 1371  | 
structure BasicTerm: BASIC_TERM = Term;  | 
1372  | 
open BasicTerm;  |