4 Copyright 1996 TU Muenchen |
4 Copyright 1996 TU Muenchen |
5 |
5 |
6 Instances of type schemes |
6 Instances of type schemes |
7 *) |
7 *) |
8 |
8 |
9 Instance = Type + |
9 theory Instance = Type: |
10 |
10 |
11 |
11 |
12 (* generic instances of a type scheme *) |
12 (* generic instances of a type scheme *) |
13 |
13 |
14 consts |
14 consts |
15 bound_typ_inst :: [subst, type_scheme] => typ |
15 bound_typ_inst :: "[subst, type_scheme] => typ" |
16 |
16 |
17 primrec |
17 primrec |
18 "bound_typ_inst S (FVar n) = (TVar n)" |
18 "bound_typ_inst S (FVar n) = (TVar n)" |
19 "bound_typ_inst S (BVar n) = (S n)" |
19 "bound_typ_inst S (BVar n) = (S n)" |
20 "bound_typ_inst S (sch1 =-> sch2) = ((bound_typ_inst S sch1) -> (bound_typ_inst S sch2))" |
20 "bound_typ_inst S (sch1 =-> sch2) = ((bound_typ_inst S sch1) -> (bound_typ_inst S sch2))" |
21 |
21 |
22 consts |
22 consts |
23 bound_scheme_inst :: [nat => type_scheme, type_scheme] => type_scheme |
23 bound_scheme_inst :: "[nat => type_scheme, type_scheme] => type_scheme" |
24 |
24 |
25 primrec |
25 primrec |
26 "bound_scheme_inst S (FVar n) = (FVar n)" |
26 "bound_scheme_inst S (FVar n) = (FVar n)" |
27 "bound_scheme_inst S (BVar n) = (S n)" |
27 "bound_scheme_inst S (BVar n) = (S n)" |
28 "bound_scheme_inst S (sch1 =-> sch2) = ((bound_scheme_inst S sch1) =-> (bound_scheme_inst S sch2))" |
28 "bound_scheme_inst S (sch1 =-> sch2) = ((bound_scheme_inst S sch1) =-> (bound_scheme_inst S sch2))" |
29 |
29 |
30 consts |
30 consts |
31 "<|" :: [typ, type_scheme] => bool (infixr 70) |
31 "<|" :: "[typ, type_scheme] => bool" (infixr 70) |
32 defs |
32 defs |
33 is_bound_typ_instance "t <| sch == ? S. t = (bound_typ_inst S sch)" |
33 is_bound_typ_instance: "t <| sch == ? S. t = (bound_typ_inst S sch)" |
34 |
34 |
35 instance type_scheme :: ord |
35 instance type_scheme :: ord .. |
36 defs le_type_scheme_def "sch' <= (sch::type_scheme) == !t. t <| sch' --> t <| sch" |
36 defs le_type_scheme_def: "sch' <= (sch::type_scheme) == !t. t <| sch' --> t <| sch" |
37 |
37 |
38 consts |
38 consts |
39 subst_to_scheme :: [nat => type_scheme, typ] => type_scheme |
39 subst_to_scheme :: "[nat => type_scheme, typ] => type_scheme" |
40 |
40 |
41 primrec |
41 primrec |
42 "subst_to_scheme B (TVar n) = (B n)" |
42 "subst_to_scheme B (TVar n) = (B n)" |
43 "subst_to_scheme B (t1 -> t2) = ((subst_to_scheme B t1) =-> (subst_to_scheme B t2))" |
43 "subst_to_scheme B (t1 -> t2) = ((subst_to_scheme B t1) =-> (subst_to_scheme B t2))" |
44 |
44 |
45 instance list :: (ord)ord |
45 instance list :: (ord)ord .. |
46 defs le_env_def |
46 defs le_env_def: |
47 "A <= B == length B = length A & (!i. i < length A --> A!i <= B!i)" |
47 "A <= B == length B = length A & (!i. i < length A --> A!i <= B!i)" |
48 |
48 |
|
49 |
|
50 (* lemmatas for instatiation *) |
|
51 |
|
52 |
|
53 (* lemmatas for bound_typ_inst *) |
|
54 |
|
55 lemma bound_typ_inst_mk_scheme: "bound_typ_inst S (mk_scheme t) = t" |
|
56 apply (induct_tac "t") |
|
57 apply (simp_all (no_asm_simp)) |
|
58 done |
|
59 |
|
60 declare bound_typ_inst_mk_scheme [simp] |
|
61 |
|
62 lemma bound_typ_inst_composed_subst: "bound_typ_inst ($S o R) ($S sch) = $S (bound_typ_inst R sch)" |
|
63 apply (induct_tac "sch") |
|
64 apply simp_all |
|
65 done |
|
66 |
|
67 declare bound_typ_inst_composed_subst [simp] |
|
68 |
|
69 lemma bound_typ_inst_eq: "S = S' ==> sch = sch' ==> bound_typ_inst S sch = bound_typ_inst S' sch'" |
|
70 apply simp |
|
71 done |
|
72 |
|
73 |
|
74 |
|
75 (* lemmatas for bound_scheme_inst *) |
|
76 |
|
77 lemma bound_scheme_inst_mk_scheme: "bound_scheme_inst B (mk_scheme t) = mk_scheme t" |
|
78 apply (induct_tac "t") |
|
79 apply (simp (no_asm)) |
|
80 apply (simp (no_asm_simp)) |
|
81 done |
|
82 |
|
83 declare bound_scheme_inst_mk_scheme [simp] |
|
84 |
|
85 lemma substitution_lemma: "$S (bound_scheme_inst B sch) = (bound_scheme_inst ($S o B) ($ S sch))" |
|
86 apply (induct_tac "sch") |
|
87 apply (simp (no_asm)) |
|
88 apply (simp (no_asm)) |
|
89 apply (simp (no_asm_simp)) |
|
90 done |
|
91 |
|
92 lemma bound_scheme_inst_type [rule_format (no_asm)]: "!t. mk_scheme t = bound_scheme_inst B sch --> |
|
93 (? S. !x:bound_tv sch. B x = mk_scheme (S x))" |
|
94 apply (induct_tac "sch") |
|
95 apply (simp (no_asm)) |
|
96 apply safe |
|
97 apply (rule exI) |
|
98 apply (rule ballI) |
|
99 apply (rule sym) |
|
100 apply simp |
|
101 apply simp |
|
102 apply (drule mk_scheme_Fun) |
|
103 apply (erule exE)+ |
|
104 apply (erule conjE) |
|
105 apply (drule sym) |
|
106 apply (drule sym) |
|
107 apply (drule mp, fast)+ |
|
108 apply safe |
|
109 apply (rename_tac S1 S2) |
|
110 apply (rule_tac x = "%x. if x:bound_tv type_scheme1 then (S1 x) else (S2 x) " in exI) |
|
111 apply auto |
|
112 done |
|
113 |
|
114 |
|
115 (* lemmas for subst_to_scheme *) |
|
116 |
|
117 lemma subst_to_scheme_inverse [rule_format (no_asm)]: "new_tv n sch --> subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) |
|
118 (bound_typ_inst (%k. TVar (k + n)) sch) = sch" |
|
119 apply (induct_tac "sch") |
|
120 apply (simp (no_asm) add: le_def) |
|
121 apply (simp (no_asm) add: le_add2 diff_add_inverse2) |
|
122 apply (simp (no_asm_simp)) |
|
123 done |
|
124 |
|
125 lemma aux: "t = t' ==> |
|
126 subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) t = |
|
127 subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) t'" |
|
128 apply fast |
|
129 done |
|
130 |
|
131 lemma aux2 [rule_format]: "new_tv n sch --> |
|
132 subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k) (bound_typ_inst S sch) = |
|
133 bound_scheme_inst ((subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k)) o S) sch" |
|
134 apply (induct_tac "sch") |
|
135 apply auto |
|
136 done |
|
137 |
|
138 |
|
139 (* lemmata for <= *) |
|
140 |
|
141 lemma le_type_scheme_def2: |
|
142 "!!(sch::type_scheme) sch'. |
|
143 (sch' <= sch) = (? B. sch' = bound_scheme_inst B sch)" |
|
144 |
|
145 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
146 apply (rule iffI) |
|
147 apply (cut_tac sch = "sch" in fresh_variable_type_schemes) |
|
148 apply (cut_tac sch = "sch'" in fresh_variable_type_schemes) |
|
149 apply (drule make_one_new_out_of_two) |
|
150 apply assumption |
|
151 apply (erule_tac V = "? n. new_tv n sch'" in thin_rl) |
|
152 apply (erule exE) |
|
153 apply (erule allE) |
|
154 apply (drule mp) |
|
155 apply (rule_tac x = " (%k. TVar (k + n))" in exI) |
|
156 apply (rule refl) |
|
157 apply (erule exE) |
|
158 apply (erule conjE)+ |
|
159 apply (drule_tac n = "n" in aux) |
|
160 apply (simp add: subst_to_scheme_inverse) |
|
161 apply (rule_tac x = " (subst_to_scheme (%k. if n <= k then BVar (k - n) else FVar k)) o S" in exI) |
|
162 apply (simp (no_asm_simp) add: aux2) |
|
163 apply safe |
|
164 apply (rule_tac x = "%n. bound_typ_inst S (B n) " in exI) |
|
165 apply (induct_tac "sch") |
|
166 apply (simp (no_asm)) |
|
167 apply (simp (no_asm)) |
|
168 apply (simp (no_asm_simp)) |
|
169 done |
|
170 |
|
171 lemma le_type_eq_is_bound_typ_instance [rule_format (no_asm)]: "(mk_scheme t) <= sch = t <| sch" |
|
172 apply (unfold is_bound_typ_instance) |
|
173 apply (simp (no_asm) add: le_type_scheme_def2) |
|
174 apply (rule iffI) |
|
175 apply (erule exE) |
|
176 apply (frule bound_scheme_inst_type) |
|
177 apply (erule exE) |
|
178 apply (rule exI) |
|
179 apply (rule mk_scheme_injective) |
|
180 apply simp |
|
181 apply (rotate_tac 1) |
|
182 apply (rule mp) |
|
183 prefer 2 apply (assumption) |
|
184 apply (induct_tac "sch") |
|
185 apply (simp (no_asm)) |
|
186 apply simp |
|
187 apply fast |
|
188 apply (intro strip) |
|
189 apply simp |
|
190 apply (erule exE) |
|
191 apply simp |
|
192 apply (rule exI) |
|
193 apply (induct_tac "sch") |
|
194 apply (simp (no_asm)) |
|
195 apply (simp (no_asm)) |
|
196 apply simp |
|
197 done |
|
198 |
|
199 lemma le_env_Cons: |
|
200 "(sch # A <= sch' # B) = (sch <= (sch'::type_scheme) & A <= B)" |
|
201 apply (unfold le_env_def) |
|
202 apply (simp (no_asm)) |
|
203 apply (rule iffI) |
|
204 apply clarify |
|
205 apply (rule conjI) |
|
206 apply (erule_tac x = "0" in allE) |
|
207 apply simp |
|
208 apply (rule conjI, assumption) |
|
209 apply clarify |
|
210 apply (erule_tac x = "Suc i" in allE) |
|
211 apply simp |
|
212 apply (rule conjI) |
|
213 apply fast |
|
214 apply (rule allI) |
|
215 apply (induct_tac "i") |
|
216 apply (simp_all (no_asm_simp)) |
|
217 done |
|
218 declare le_env_Cons [iff] |
|
219 |
|
220 lemma is_bound_typ_instance_closed_subst: "t <| sch ==> $S t <| $S sch" |
|
221 apply (unfold is_bound_typ_instance) |
|
222 apply (erule exE) |
|
223 apply (rename_tac "SA") |
|
224 apply (simp) |
|
225 apply (rule_tac x = "$S o SA" in exI) |
|
226 apply (simp (no_asm)) |
|
227 done |
|
228 |
|
229 lemma S_compatible_le_scheme: "!!(sch::type_scheme) sch'. sch' <= sch ==> $S sch' <= $ S sch" |
|
230 apply (simp add: le_type_scheme_def2) |
|
231 apply (erule exE) |
|
232 apply (simp add: substitution_lemma) |
|
233 apply fast |
|
234 done |
|
235 |
|
236 lemma S_compatible_le_scheme_lists: |
|
237 "!!(A::type_scheme list) A'. A' <= A ==> $S A' <= $ S A" |
|
238 apply (unfold le_env_def app_subst_list) |
|
239 apply (simp (no_asm) cong add: conj_cong) |
|
240 apply (fast intro!: S_compatible_le_scheme) |
|
241 done |
|
242 |
|
243 lemma bound_typ_instance_trans: "[| t <| sch; sch <= sch' |] ==> t <| sch'" |
|
244 apply (unfold le_type_scheme_def) |
|
245 apply fast |
|
246 done |
|
247 |
|
248 lemma le_type_scheme_refl: "sch <= (sch::type_scheme)" |
|
249 apply (unfold le_type_scheme_def) |
|
250 apply fast |
|
251 done |
|
252 declare le_type_scheme_refl [iff] |
|
253 |
|
254 lemma le_env_refl: "A <= (A::type_scheme list)" |
|
255 apply (unfold le_env_def) |
|
256 apply fast |
|
257 done |
|
258 declare le_env_refl [iff] |
|
259 |
|
260 lemma bound_typ_instance_BVar: "sch <= BVar n" |
|
261 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
262 apply (intro strip) |
|
263 apply (rule_tac x = "%a. t" in exI) |
|
264 apply (simp (no_asm)) |
|
265 done |
|
266 declare bound_typ_instance_BVar [iff] |
|
267 |
|
268 lemma le_FVar: |
|
269 "(sch <= FVar n) = (sch = FVar n)" |
|
270 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
271 apply (induct_tac "sch") |
|
272 apply (simp (no_asm)) |
|
273 apply (simp (no_asm)) |
|
274 apply fast |
|
275 apply simp |
|
276 apply fast |
|
277 done |
|
278 declare le_FVar [simp] |
|
279 |
|
280 lemma not_FVar_le_Fun: "~(FVar n <= sch1 =-> sch2)" |
|
281 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
282 apply (simp (no_asm)) |
|
283 done |
|
284 declare not_FVar_le_Fun [iff] |
|
285 |
|
286 lemma not_BVar_le_Fun: "~(BVar n <= sch1 =-> sch2)" |
|
287 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
288 apply (simp (no_asm)) |
|
289 apply (rule_tac x = "TVar n" in exI) |
|
290 apply (simp (no_asm)) |
|
291 apply fast |
|
292 done |
|
293 declare not_BVar_le_Fun [iff] |
|
294 |
|
295 lemma Fun_le_FunD: |
|
296 "(sch1 =-> sch2 <= sch1' =-> sch2') ==> sch1 <= sch1' & sch2 <= sch2'" |
|
297 apply (unfold le_type_scheme_def is_bound_typ_instance) |
|
298 apply (fastsimp) |
|
299 done |
|
300 |
|
301 lemma scheme_le_Fun [rule_format (no_asm)]: "(sch' <= sch1 =-> sch2) --> (? sch'1 sch'2. sch' = sch'1 =-> sch'2)" |
|
302 apply (induct_tac "sch'") |
|
303 apply (simp (no_asm_simp)) |
|
304 apply (simp (no_asm_simp)) |
|
305 apply fast |
|
306 done |
|
307 |
|
308 lemma le_type_scheme_free_tv [rule_format (no_asm)]: "!sch'::type_scheme. sch <= sch' --> free_tv sch' <= free_tv sch" |
|
309 apply (induct_tac "sch") |
|
310 apply (rule allI) |
|
311 apply (induct_tac "sch'") |
|
312 apply (simp (no_asm)) |
|
313 apply (simp (no_asm)) |
|
314 apply (simp (no_asm)) |
|
315 apply (rule allI) |
|
316 apply (induct_tac "sch'") |
|
317 apply (simp (no_asm)) |
|
318 apply (simp (no_asm)) |
|
319 apply (simp (no_asm)) |
|
320 apply (rule allI) |
|
321 apply (induct_tac "sch'") |
|
322 apply (simp (no_asm)) |
|
323 apply (simp (no_asm)) |
|
324 apply simp |
|
325 apply (intro strip) |
|
326 apply (drule Fun_le_FunD) |
|
327 apply fast |
|
328 done |
|
329 |
|
330 lemma le_env_free_tv [rule_format (no_asm)]: "!A::type_scheme list. A <= B --> free_tv B <= free_tv A" |
|
331 apply (induct_tac "B") |
|
332 apply (simp (no_asm)) |
|
333 apply (rule allI) |
|
334 apply (induct_tac "A") |
|
335 apply (simp (no_asm) add: le_env_def) |
|
336 apply (simp (no_asm)) |
|
337 apply (fast dest: le_type_scheme_free_tv) |
|
338 done |
|
339 |
|
340 |
49 end |
341 end |