4 Copyright 1996 TU Muenchen |
4 Copyright 1996 TU Muenchen |
5 |
5 |
6 Generalizing type schemes with respect to a context |
6 Generalizing type schemes with respect to a context |
7 *) |
7 *) |
8 |
8 |
9 Generalize = Instance + |
9 theory Generalize = Instance: |
10 |
10 |
11 |
11 |
12 (* gen: binding (generalising) the variables which are not free in the context *) |
12 (* gen: binding (generalising) the variables which are not free in the context *) |
13 |
13 |
14 types ctxt = type_scheme list |
14 types ctxt = "type_scheme list" |
15 |
15 |
16 consts |
16 consts |
17 gen :: [ctxt, typ] => type_scheme |
17 gen :: "[ctxt, typ] => type_scheme" |
18 |
18 |
19 primrec |
19 primrec |
20 "gen A (TVar n) = (if (n:(free_tv A)) then (FVar n) else (BVar n))" |
20 "gen A (TVar n) = (if (n:(free_tv A)) then (FVar n) else (BVar n))" |
21 "gen A (t1 -> t2) = (gen A t1) =-> (gen A t2)" |
21 "gen A (t1 -> t2) = (gen A t1) =-> (gen A t2)" |
22 |
22 |
23 (* executable version of gen: Implementation with free_tv_ML *) |
23 (* executable version of gen: Implementation with free_tv_ML *) |
24 |
24 |
25 consts |
25 consts |
26 gen_ML_aux :: [nat list, typ] => type_scheme |
26 gen_ML_aux :: "[nat list, typ] => type_scheme" |
27 |
|
28 primrec |
27 primrec |
29 "gen_ML_aux A (TVar n) = (if (n: set A) then (FVar n) else (BVar n))" |
28 "gen_ML_aux A (TVar n) = (if (n: set A) then (FVar n) else (BVar n))" |
30 "gen_ML_aux A (t1 -> t2) = (gen_ML_aux A t1) =-> (gen_ML_aux A t2)" |
29 "gen_ML_aux A (t1 -> t2) = (gen_ML_aux A t1) =-> (gen_ML_aux A t2)" |
31 |
30 |
32 consts |
31 consts |
33 gen_ML :: [ctxt, typ] => type_scheme |
32 gen_ML :: "[ctxt, typ] => type_scheme" |
|
33 defs |
|
34 gen_ML_def: "gen_ML A t == gen_ML_aux (free_tv_ML A) t" |
34 |
35 |
35 defs |
36 |
36 gen_ML_def "gen_ML A t == gen_ML_aux (free_tv_ML A) t" |
37 declare equalityE [elim!] |
|
38 |
|
39 lemma gen_eq_on_free_tv: "free_tv A = free_tv B ==> gen A t = gen B t" |
|
40 apply (induct_tac "t") |
|
41 apply (simp_all (no_asm_simp)) |
|
42 done |
|
43 |
|
44 lemma gen_without_effect [rule_format (no_asm)]: "(free_tv t) <= (free_tv sch) --> gen sch t = (mk_scheme t)" |
|
45 apply (induct_tac "t") |
|
46 apply (simp (no_asm_simp)) |
|
47 apply (simp (no_asm)) |
|
48 apply fast |
|
49 done |
|
50 |
|
51 declare gen_without_effect [simp] |
|
52 |
|
53 lemma free_tv_gen: "free_tv (gen ($ S A) t) = free_tv t Int free_tv ($ S A)" |
|
54 apply (induct_tac "t") |
|
55 apply (simp (no_asm)) |
|
56 apply (case_tac "nat : free_tv ($ S A) ") |
|
57 apply (simp (no_asm_simp)) |
|
58 apply fast |
|
59 apply (simp (no_asm_simp)) |
|
60 apply fast |
|
61 apply simp |
|
62 apply fast |
|
63 done |
|
64 |
|
65 declare free_tv_gen [simp] |
|
66 |
|
67 lemma free_tv_gen_cons: "free_tv (gen ($ S A) t # $ S A) = free_tv ($ S A)" |
|
68 apply (simp (no_asm)) |
|
69 apply fast |
|
70 done |
|
71 |
|
72 declare free_tv_gen_cons [simp] |
|
73 |
|
74 lemma bound_tv_gen: "bound_tv (gen A t1) = (free_tv t1) - (free_tv A)" |
|
75 apply (induct_tac "t1") |
|
76 apply (simp (no_asm)) |
|
77 apply (case_tac "nat : free_tv A") |
|
78 apply (simp (no_asm_simp)) |
|
79 apply (simp (no_asm_simp)) |
|
80 apply fast |
|
81 apply (simp (no_asm_simp)) |
|
82 apply fast |
|
83 done |
|
84 |
|
85 declare bound_tv_gen [simp] |
|
86 |
|
87 lemma new_tv_compatible_gen [rule_format (no_asm)]: "new_tv n t --> new_tv n (gen A t)" |
|
88 apply (induct_tac "t") |
|
89 apply auto |
|
90 done |
|
91 |
|
92 lemma gen_eq_gen_ML: "gen A t = gen_ML A t" |
|
93 apply (unfold gen_ML_def) |
|
94 apply (induct_tac "t") |
|
95 apply (simp (no_asm) add: free_tv_ML_scheme_list) |
|
96 apply (simp (no_asm_simp) add: free_tv_ML_scheme_list) |
|
97 done |
|
98 |
|
99 lemma gen_subst_commutes [rule_format (no_asm)]: "(free_tv S) Int ((free_tv t) - (free_tv A)) = {} |
|
100 --> gen ($ S A) ($ S t) = $ S (gen A t)" |
|
101 apply (induct_tac "t") |
|
102 apply (intro strip) |
|
103 apply (case_tac "nat: (free_tv A) ") |
|
104 apply (simp (no_asm_simp)) |
|
105 apply simp |
|
106 apply (subgoal_tac "nat ~: free_tv S") |
|
107 prefer 2 apply (fast) |
|
108 apply (simp add: free_tv_subst dom_def) |
|
109 apply (cut_tac free_tv_app_subst_scheme_list) |
|
110 apply fast |
|
111 apply (simp (no_asm_simp)) |
|
112 apply blast |
|
113 done |
|
114 |
|
115 lemma bound_typ_inst_gen [rule_format (no_asm)]: "free_tv(t::typ) <= free_tv(A) --> bound_typ_inst S (gen A t) = t" |
|
116 apply (induct_tac "t") |
|
117 apply (simp_all (no_asm_simp)) |
|
118 apply fast |
|
119 done |
|
120 declare bound_typ_inst_gen [simp] |
|
121 |
|
122 lemma gen_bound_typ_instance: |
|
123 "gen ($ S A) ($ S t) <= $ S (gen A t)" |
|
124 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
125 apply safe |
|
126 apply (rename_tac "R") |
|
127 apply (rule_tac x = " (%a. bound_typ_inst R (gen ($S A) (S a))) " in exI) |
|
128 apply (induct_tac "t") |
|
129 apply (simp (no_asm)) |
|
130 apply (simp (no_asm_simp)) |
|
131 done |
|
132 |
|
133 lemma free_tv_subset_gen_le: |
|
134 "free_tv B <= free_tv A ==> gen A t <= gen B t" |
|
135 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
136 apply safe |
|
137 apply (rename_tac "S") |
|
138 apply (rule_tac x = "%b. if b:free_tv A then TVar b else S b" in exI) |
|
139 apply (induct_tac "t") |
|
140 apply (simp (no_asm_simp)) |
|
141 apply fast |
|
142 apply (simp (no_asm_simp)) |
|
143 done |
|
144 |
|
145 lemma gen_t_le_gen_alpha_t [rule_format (no_asm)]: |
|
146 "new_tv n A --> |
|
147 gen A t <= gen A ($ (%x. TVar (if x : free_tv A then x else n + x)) t)" |
|
148 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
149 apply (intro strip) |
|
150 apply (erule exE) |
|
151 apply (hypsubst) |
|
152 apply (rule_tac x = " (%x. S (if n <= x then x - n else x))" in exI) |
|
153 apply (induct_tac "t") |
|
154 apply (simp (no_asm)) |
|
155 apply (case_tac "nat : free_tv A") |
|
156 apply (simp (no_asm_simp)) |
|
157 apply (simp (no_asm_simp)) |
|
158 apply (subgoal_tac "n <= n + nat") |
|
159 apply (frule_tac t = "A" in new_tv_le) |
|
160 apply assumption |
|
161 apply (drule new_tv_not_free_tv) |
|
162 apply (drule new_tv_not_free_tv) |
|
163 apply (simp (no_asm_simp) add: diff_add_inverse) |
|
164 apply (simp (no_asm) add: le_add1) |
|
165 apply (simp (no_asm_simp)) |
|
166 done |
|
167 |
|
168 declare gen_t_le_gen_alpha_t [simp] |
|
169 |
37 |
170 |
38 end |
171 end |