| author | wenzelm | 
| Sun, 15 Sep 2024 14:06:06 +0200 | |
| changeset 80879 | fb1dd189c4f3 | 
| parent 79433 | 88341f610b33 | 
| child 81259 | 1c2be1fca2bd | 
| permissions | -rw-r--r-- | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
1  | 
(* Title: Pure/type_infer.ML  | 
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
2  | 
Author: Stefan Berghofer and Markus Wenzel, TU Muenchen  | 
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
3  | 
|
| 
42405
 
13ecdb3057d8
split Type_Infer into early and late part, after Proof_Context;
 
wenzelm 
parents: 
42400 
diff
changeset
 | 
4  | 
Basic representation of type-inference problems.  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
5  | 
*)  | 
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
6  | 
|
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
7  | 
signature TYPE_INFER =  | 
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
8  | 
sig  | 
| 24504 | 9  | 
val is_param: indexname -> bool  | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
10  | 
val is_paramT: typ -> bool  | 
| 
42400
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
11  | 
val param_maxidx: term -> int -> int  | 
| 
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
12  | 
val param_maxidx_of: term list -> int  | 
| 
14788
 
9776f0c747c8
incorporate type inference interface from type.ML;
 
wenzelm 
parents: 
14695 
diff
changeset
 | 
13  | 
val param: int -> string * sort -> typ  | 
| 40286 | 14  | 
val mk_param: int -> sort -> typ  | 
| 39296 | 15  | 
val anyT: sort -> typ  | 
| 22771 | 16  | 
val paramify_vars: typ -> typ  | 
| 39296 | 17  | 
val deref: typ Vartab.table -> typ -> typ  | 
18  | 
val finish: Proof.context -> typ Vartab.table -> typ list * term list -> typ list * term list  | 
|
| 
62958
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
19  | 
val object_logic: bool Config.T  | 
| 
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
20  | 
val fixate: Proof.context -> bool -> term list -> term list  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
21  | 
end;  | 
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
22  | 
|
| 
37145
 
01aa36932739
renamed structure TypeInfer to Type_Infer, keeping the old name as legacy alias for some time;
 
wenzelm 
parents: 
35013 
diff
changeset
 | 
23  | 
structure Type_Infer: TYPE_INFER =  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
24  | 
struct  | 
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
25  | 
|
| 22698 | 26  | 
(** type parameters and constraints **)  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
27  | 
|
| 39286 | 28  | 
(* type inference parameters -- may get instantiated *)  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
29  | 
|
| 24504 | 30  | 
fun is_param (x, _: int) = String.isPrefix "?" x;  | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
31  | 
|
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
32  | 
fun is_paramT (TVar (xi, _)) = is_param xi  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
33  | 
| is_paramT _ = false;  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
34  | 
|
| 
42400
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
35  | 
val param_maxidx =  | 
| 
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
36  | 
(Term.fold_types o Term.fold_atyps)  | 
| 
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
37  | 
(fn (TVar (xi as (_, i), _)) => if is_param xi then Integer.max i else I | _ => I);  | 
| 
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
38  | 
|
| 
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
39  | 
fun param_maxidx_of ts = fold param_maxidx ts ~1;  | 
| 
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
40  | 
|
| 22698 | 41  | 
fun param i (x, S) = TVar (("?" ^ x, i), S);
 | 
42  | 
||
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
43  | 
fun mk_param i S = TVar (("?'a", i), S);
 | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
44  | 
|
| 39296 | 45  | 
|
46  | 
(* pre-stage parameters *)  | 
|
47  | 
||
48  | 
fun anyT S = TFree ("'_dummy_", S);
 | 
|
49  | 
||
| 
32002
 
1a35de4112bb
tuned paramify_vars: Term_Subst.map_atypsT_option;
 
wenzelm 
parents: 
31977 
diff
changeset
 | 
50  | 
val paramify_vars =  | 
| 79409 | 51  | 
Term.map_atyps (fn TVar ((x, i), S) => param i (x, S) | _ => raise Same.SAME);  | 
| 22771 | 52  | 
|
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
53  | 
|
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
54  | 
|
| 39296 | 55  | 
(** results **)  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
56  | 
|
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
57  | 
(* dereferenced views *)  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
58  | 
|
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
59  | 
fun deref tye (T as TVar (xi, _)) =  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
60  | 
(case Vartab.lookup tye xi of  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
61  | 
NONE => T  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
62  | 
| SOME U => deref tye U)  | 
| 
42400
 
26c8c9cabb24
more precise treatment of existing type inference parameters;
 
wenzelm 
parents: 
42386 
diff
changeset
 | 
63  | 
| deref _ T = T;  | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
64  | 
|
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
65  | 
fun add_parms tye T =  | 
| 32146 | 66  | 
(case deref tye T of  | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
67  | 
Type (_, Ts) => fold (add_parms tye) Ts  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
68  | 
| TVar (xi, _) => if is_param xi then insert (op =) xi else I  | 
| 32146 | 69  | 
| _ => I);  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
70  | 
|
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
71  | 
fun add_names tye T =  | 
| 32146 | 72  | 
(case deref tye T of  | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
73  | 
Type (_, Ts) => fold (add_names tye) Ts  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
74  | 
| TFree (x, _) => Name.declare x  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
75  | 
| TVar ((x, i), _) => if is_param (x, i) then I else Name.declare x);  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
76  | 
|
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
77  | 
|
| 39296 | 78  | 
(* finish -- standardize remaining parameters *)  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
79  | 
|
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
80  | 
fun finish ctxt tye (Ts, ts) =  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
81  | 
let  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
82  | 
val used =  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
83  | 
(fold o fold_types) (add_names tye) ts (fold (add_names tye) Ts (Variable.names_of ctxt));  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
84  | 
val parms = rev ((fold o fold_types) (add_parms tye) ts (fold (add_parms tye) Ts []));  | 
| 
43329
 
84472e198515
tuned signature: Name.invent and Name.invent_names;
 
wenzelm 
parents: 
42405 
diff
changeset
 | 
85  | 
    val names = Name.invent used ("?" ^ Name.aT) (length parms);
 | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
86  | 
val tab = Vartab.make (parms ~~ names);  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
87  | 
|
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
88  | 
fun finish_typ T =  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
89  | 
(case deref tye T of  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
90  | 
Type (a, Ts) => Type (a, map finish_typ Ts)  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
91  | 
| U as TFree _ => U  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
92  | 
| U as TVar (xi, S) =>  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
93  | 
(case Vartab.lookup tab xi of  | 
| 
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
94  | 
NONE => U  | 
| 
39295
 
6e8b0672c6a2
Type_Infer.finish: index 0 -- freshness supposedly via Name.invents;
 
wenzelm 
parents: 
39294 
diff
changeset
 | 
95  | 
| SOME a => TVar ((a, 0), S)));  | 
| 
39294
 
27fae73fe769
simplified Type_Infer: eliminated separate datatypes pretyp/preterm -- only assign is_paramT TVars;
 
wenzelm 
parents: 
39292 
diff
changeset
 | 
96  | 
in (map finish_typ Ts, map (Type.strip_constraints o Term.map_types finish_typ) ts) end;  | 
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
97  | 
|
| 
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
98  | 
|
| 39296 | 99  | 
(* fixate -- introduce fresh type variables *)  | 
100  | 
||
| 69575 | 101  | 
val object_logic = Config.declare_bool ("Type_Infer.object_logic", \<^here>) (K true);
 | 
| 
62958
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
102  | 
|
| 
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
103  | 
fun fixate ctxt pattern ts =  | 
| 39296 | 104  | 
let  | 
| 
62958
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
105  | 
val base_sort = Object_Logic.get_base_sort ctxt;  | 
| 
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
106  | 
val improve_sort =  | 
| 
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
107  | 
if is_some base_sort andalso not pattern andalso Config.get ctxt object_logic  | 
| 
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
108  | 
then fn [] => the base_sort | S => S else I;  | 
| 
 
b41c1cb5e251
Type_Infer.object_logic controls improvement of type inference result;
 
wenzelm 
parents: 
53672 
diff
changeset
 | 
109  | 
|
| 39296 | 110  | 
fun subst_param (xi, S) (inst, used) =  | 
111  | 
if is_param xi then  | 
|
112  | 
let  | 
|
| 
43329
 
84472e198515
tuned signature: Name.invent and Name.invent_names;
 
wenzelm 
parents: 
42405 
diff
changeset
 | 
113  | 
val [a] = Name.invent used Name.aT 1;  | 
| 39296 | 114  | 
val used' = Name.declare a used;  | 
| 74266 | 115  | 
in (TVars.add ((xi, S), TFree (a, improve_sort S)) inst, used') end  | 
| 39296 | 116  | 
else (inst, used);  | 
| 74281 | 117  | 
val params = TVars.build (fold TVars.add_tvars ts) |> TVars.list_set;  | 
| 39296 | 118  | 
val used = (fold o fold_types) Term.declare_typ_names ts (Variable.names_of ctxt);  | 
| 74281 | 119  | 
val (inst, _) = fold subst_param params (TVars.empty, used);  | 
| 79433 | 120  | 
in (Same.commit o Same.map o Term.map_types_same) (Term_Subst.instantiateT_same inst) ts end;  | 
| 39296 | 121  | 
|
| 
2957
 
d35fca99b3be
Type inference (isolated from type.ML, completely reimplemented).
 
wenzelm 
parents:  
diff
changeset
 | 
122  | 
end;  |