|
1300
|
1 |
(* Title: HOL/MiniML/MiniML.thy
|
|
|
2 |
ID: $Id$
|
|
14422
|
3 |
Author: Dieter Nazareth, Wolfgang Naraschewski and Tobias Nipkow
|
|
2525
|
4 |
Copyright 1996 TU Muenchen
|
|
1300
|
5 |
|
|
|
6 |
Mini_ML with type inference rules.
|
|
|
7 |
*)
|
|
|
8 |
|
|
14422
|
9 |
theory MiniML = Generalize:
|
|
1300
|
10 |
|
|
|
11 |
(* expressions *)
|
|
|
12 |
datatype
|
|
2525
|
13 |
expr = Var nat | Abs expr | App expr expr | LET expr expr
|
|
1300
|
14 |
|
|
|
15 |
(* type inference rules *)
|
|
|
16 |
consts
|
|
2525
|
17 |
has_type :: "(ctxt * expr * typ)set"
|
|
1300
|
18 |
syntax
|
|
14422
|
19 |
"@has_type" :: "[ctxt, expr, typ] => bool"
|
|
1525
|
20 |
("((_) |-/ (_) :: (_))" [60,0,60] 60)
|
|
1300
|
21 |
translations
|
|
2525
|
22 |
"A |- e :: t" == "(A,e,t):has_type"
|
|
1300
|
23 |
|
|
1790
|
24 |
inductive has_type
|
|
14422
|
25 |
intros
|
|
|
26 |
VarI: "[| n < length A; t <| A!n |] ==> A |- Var n :: t"
|
|
|
27 |
AbsI: "[| (mk_scheme t1)#A |- e :: t2 |] ==> A |- Abs e :: t1 -> t2"
|
|
|
28 |
AppI: "[| A |- e1 :: t2 -> t1; A |- e2 :: t2 |]
|
|
|
29 |
==> A |- App e1 e2 :: t1"
|
|
|
30 |
LETI: "[| A |- e1 :: t1; (gen A t1)#A |- e2 :: t |] ==> A |- LET e1 e2 :: t"
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
declare has_type.intros [simp]
|
|
|
34 |
declare Un_upper1 [simp] Un_upper2 [simp]
|
|
|
35 |
|
|
|
36 |
declare is_bound_typ_instance_closed_subst [simp]
|
|
|
37 |
|
|
|
38 |
|
|
|
39 |
lemma s'_t_equals_s_t: "!!t::typ. $(%n. if n : (free_tv A) Un (free_tv t) then (S n) else (TVar n)) t = $S t"
|
|
|
40 |
apply (rule typ_substitutions_only_on_free_variables)
|
|
|
41 |
apply (simp add: Ball_def)
|
|
|
42 |
done
|
|
|
43 |
|
|
|
44 |
declare s'_t_equals_s_t [simp]
|
|
|
45 |
|
|
|
46 |
lemma s'_a_equals_s_a: "!!A::type_scheme list. $(%n. if n : (free_tv A) Un (free_tv t) then (S n) else (TVar n)) A = $S A"
|
|
|
47 |
apply (rule scheme_list_substitutions_only_on_free_variables)
|
|
|
48 |
apply (simp add: Ball_def)
|
|
|
49 |
done
|
|
|
50 |
|
|
|
51 |
declare s'_a_equals_s_a [simp]
|
|
|
52 |
|
|
|
53 |
lemma replace_s_by_s':
|
|
|
54 |
"$(%n. if n : (free_tv A) Un (free_tv t) then S n else TVar n) A |-
|
|
|
55 |
e :: $(%n. if n : (free_tv A) Un (free_tv t) then S n else TVar n) t
|
|
|
56 |
==> $S A |- e :: $S t"
|
|
|
57 |
|
|
|
58 |
apply (rule_tac P = "%A. A |- e :: $S t" in ssubst)
|
|
|
59 |
apply (rule s'_a_equals_s_a [symmetric])
|
|
|
60 |
apply (rule_tac P = "%t. $ (%n. if n : free_tv A Un free_tv (?t1 S) then S n else TVar n) A |- e :: t" in ssubst)
|
|
|
61 |
apply (rule s'_t_equals_s_t [symmetric])
|
|
|
62 |
apply simp
|
|
|
63 |
done
|
|
|
64 |
|
|
|
65 |
lemma alpha_A': "!!A::type_scheme list. $ (%x. TVar (if x : free_tv A then x else n + x)) A = $ id_subst A"
|
|
|
66 |
apply (rule scheme_list_substitutions_only_on_free_variables)
|
|
|
67 |
apply (simp add: id_subst_def)
|
|
|
68 |
done
|
|
|
69 |
|
|
|
70 |
lemma alpha_A: "!!A::type_scheme list. $ (%x. TVar (if x : free_tv A then x else n + x)) A = A"
|
|
|
71 |
apply (rule alpha_A' [THEN ssubst])
|
|
|
72 |
apply simp
|
|
|
73 |
done
|
|
|
74 |
|
|
|
75 |
lemma S_o_alpha_typ: "$ (S o alpha) (t::typ) = $ S ($ (%x. TVar (alpha x)) t)"
|
|
|
76 |
apply (induct_tac "t")
|
|
|
77 |
apply (simp_all)
|
|
|
78 |
done
|
|
|
79 |
|
|
|
80 |
lemma S_o_alpha_typ': "$ (%u. (S o alpha) u) (t::typ) = $ S ($ (%x. TVar (alpha x)) t)"
|
|
|
81 |
apply (induct_tac "t")
|
|
|
82 |
apply (simp_all)
|
|
|
83 |
done
|
|
|
84 |
|
|
|
85 |
lemma S_o_alpha_type_scheme: "$ (S o alpha) (sch::type_scheme) = $ S ($ (%x. TVar (alpha x)) sch)"
|
|
|
86 |
apply (induct_tac "sch")
|
|
|
87 |
apply (simp_all)
|
|
|
88 |
done
|
|
|
89 |
|
|
|
90 |
lemma S_o_alpha_type_scheme_list: "$ (S o alpha) (A::type_scheme list) = $ S ($ (%x. TVar (alpha x)) A)"
|
|
|
91 |
apply (induct_tac "A")
|
|
|
92 |
apply (simp_all)
|
|
|
93 |
apply (rule S_o_alpha_type_scheme [unfolded o_def])
|
|
|
94 |
done
|
|
|
95 |
|
|
|
96 |
lemma S'_A_eq_S'_alpha_A: "!!A::type_scheme list.
|
|
|
97 |
$ (%n. if n : free_tv A Un free_tv t then S n else TVar n) A =
|
|
|
98 |
$ ((%x. if x : free_tv A Un free_tv t then S x else TVar x) o
|
|
|
99 |
(%x. if x : free_tv A then x else n + x)) A"
|
|
|
100 |
apply (subst S_o_alpha_type_scheme_list)
|
|
|
101 |
apply (subst alpha_A)
|
|
|
102 |
apply (rule refl)
|
|
|
103 |
done
|
|
|
104 |
|
|
|
105 |
lemma dom_S':
|
|
|
106 |
"dom (%n. if n : free_tv A Un free_tv t then S n else TVar n) <=
|
|
|
107 |
free_tv A Un free_tv t"
|
|
|
108 |
apply (unfold free_tv_subst dom_def)
|
|
|
109 |
apply (simp (no_asm))
|
|
|
110 |
apply fast
|
|
|
111 |
done
|
|
|
112 |
|
|
|
113 |
lemma cod_S':
|
|
|
114 |
"!!(A::type_scheme list) (t::typ).
|
|
|
115 |
cod (%n. if n : free_tv A Un free_tv t then S n else TVar n) <=
|
|
|
116 |
free_tv ($ S A) Un free_tv ($ S t)"
|
|
|
117 |
apply (unfold free_tv_subst cod_def subset_def)
|
|
|
118 |
apply (rule ballI)
|
|
|
119 |
apply (erule UN_E)
|
|
|
120 |
apply (drule dom_S' [THEN subsetD])
|
|
|
121 |
apply simp
|
|
|
122 |
apply (fast dest: free_tv_of_substitutions_extend_to_scheme_lists intro: free_tv_of_substitutions_extend_to_types [THEN subsetD])
|
|
|
123 |
done
|
|
|
124 |
|
|
|
125 |
lemma free_tv_S':
|
|
|
126 |
"!!(A::type_scheme list) (t::typ).
|
|
|
127 |
free_tv (%n. if n : free_tv A Un free_tv t then S n else TVar n) <=
|
|
|
128 |
free_tv A Un free_tv ($ S A) Un free_tv t Un free_tv ($ S t)"
|
|
|
129 |
apply (unfold free_tv_subst)
|
|
|
130 |
apply (fast dest: dom_S' [THEN subsetD] cod_S' [THEN subsetD])
|
|
|
131 |
done
|
|
|
132 |
|
|
|
133 |
lemma free_tv_alpha: "!!t1::typ.
|
|
|
134 |
(free_tv ($ (%x. TVar (if x : free_tv A then x else n + x)) t1) - free_tv A) <=
|
|
|
135 |
{x. ? y. x = n + y}"
|
|
|
136 |
apply (induct_tac "t1")
|
|
|
137 |
apply (simp (no_asm))
|
|
|
138 |
apply fast
|
|
|
139 |
apply (simp (no_asm))
|
|
|
140 |
apply fast
|
|
|
141 |
done
|
|
|
142 |
|
|
|
143 |
lemma aux_plus: "!!(k::nat). n <= n + k"
|
|
|
144 |
apply (induct_tac "k" rule: nat_induct)
|
|
|
145 |
apply (simp (no_asm))
|
|
|
146 |
apply (simp (no_asm_simp))
|
|
|
147 |
done
|
|
|
148 |
|
|
|
149 |
declare aux_plus [simp]
|
|
|
150 |
|
|
|
151 |
lemma new_tv_Int_free_tv_empty_type: "!!t::typ. new_tv n t ==> {x. ? y. x = n + y} Int free_tv t = {}"
|
|
|
152 |
apply safe
|
|
|
153 |
apply (cut_tac aux_plus)
|
|
|
154 |
apply (drule new_tv_le)
|
|
|
155 |
apply assumption
|
|
|
156 |
apply (rotate_tac 1)
|
|
|
157 |
apply (drule new_tv_not_free_tv)
|
|
|
158 |
apply fast
|
|
|
159 |
done
|
|
|
160 |
|
|
|
161 |
lemma new_tv_Int_free_tv_empty_scheme: "!!sch::type_scheme. new_tv n sch ==> {x. ? y. x = n + y} Int free_tv sch = {}"
|
|
|
162 |
apply safe
|
|
|
163 |
apply (cut_tac aux_plus)
|
|
|
164 |
apply (drule new_tv_le)
|
|
|
165 |
apply assumption
|
|
|
166 |
apply (rotate_tac 1)
|
|
|
167 |
apply (drule new_tv_not_free_tv)
|
|
|
168 |
apply fast
|
|
|
169 |
done
|
|
|
170 |
|
|
|
171 |
lemma new_tv_Int_free_tv_empty_scheme_list: "!A::type_scheme list. new_tv n A --> {x. ? y. x = n + y} Int free_tv A = {}"
|
|
|
172 |
apply (rule allI)
|
|
|
173 |
apply (induct_tac "A")
|
|
|
174 |
apply (simp (no_asm))
|
|
|
175 |
apply (simp (no_asm))
|
|
|
176 |
apply (fast dest: new_tv_Int_free_tv_empty_scheme)
|
|
|
177 |
done
|
|
|
178 |
|
|
|
179 |
lemma gen_t_le_gen_alpha_t [rule_format (no_asm)]:
|
|
|
180 |
"new_tv n A --> gen A t <= gen A ($ (%x. TVar (if x : free_tv A then x else n + x)) t)"
|
|
|
181 |
apply (unfold le_type_scheme_def is_bound_typ_instance)
|
|
|
182 |
apply (intro strip)
|
|
|
183 |
apply (erule exE)
|
|
|
184 |
apply (hypsubst)
|
|
|
185 |
apply (rule_tac x = " (%x. S (if n <= x then x - n else x))" in exI)
|
|
|
186 |
apply (induct_tac "t")
|
|
|
187 |
apply (simp (no_asm))
|
|
|
188 |
apply (case_tac "nat : free_tv A")
|
|
|
189 |
apply (simp (no_asm_simp))
|
|
|
190 |
apply (subgoal_tac "n <= n + nat")
|
|
|
191 |
apply (drule new_tv_le)
|
|
|
192 |
apply assumption
|
|
|
193 |
apply (drule new_tv_not_free_tv)
|
|
|
194 |
apply (drule new_tv_not_free_tv)
|
|
|
195 |
apply (simp (no_asm_simp) add: diff_add_inverse)
|
|
|
196 |
apply (simp (no_asm))
|
|
|
197 |
apply (simp (no_asm_simp))
|
|
|
198 |
done
|
|
|
199 |
|
|
|
200 |
declare has_type.intros [intro!]
|
|
|
201 |
|
|
|
202 |
lemma has_type_le_env [rule_format (no_asm)]: "A |- e::t ==> !B. A <= B --> B |- e::t"
|
|
|
203 |
apply (erule has_type.induct)
|
|
|
204 |
apply (simp (no_asm) add: le_env_def)
|
|
|
205 |
apply (fastsimp elim: bound_typ_instance_trans)
|
|
|
206 |
apply simp
|
|
|
207 |
apply fast
|
|
|
208 |
apply (slow elim: le_env_free_tv [THEN free_tv_subset_gen_le])
|
|
|
209 |
done
|
|
|
210 |
|
|
|
211 |
(* has_type is closed w.r.t. substitution *)
|
|
|
212 |
lemma has_type_cl_sub: "A |- e :: t ==> !S. $S A |- e :: $S t"
|
|
|
213 |
apply (erule has_type.induct)
|
|
|
214 |
(* case VarI *)
|
|
|
215 |
apply (rule allI)
|
|
|
216 |
apply (rule has_type.VarI)
|
|
|
217 |
apply (simp add: app_subst_list)
|
|
|
218 |
apply (simp (no_asm_simp) add: app_subst_list)
|
|
|
219 |
(* case AbsI *)
|
|
|
220 |
apply (rule allI)
|
|
|
221 |
apply (simp (no_asm))
|
|
|
222 |
apply (rule has_type.AbsI)
|
|
|
223 |
apply simp
|
|
|
224 |
(* case AppI *)
|
|
|
225 |
apply (rule allI)
|
|
|
226 |
apply (rule has_type.AppI)
|
|
|
227 |
apply simp
|
|
|
228 |
apply (erule spec)
|
|
|
229 |
apply (erule spec)
|
|
|
230 |
(* case LetI *)
|
|
|
231 |
apply (rule allI)
|
|
|
232 |
apply (rule replace_s_by_s')
|
|
|
233 |
apply (cut_tac A = "$ S A" and A' = "A" and t = "t" and t' = "$ S t" in ex_fresh_variable)
|
|
|
234 |
apply (erule exE)
|
|
|
235 |
apply (erule conjE)+
|
|
|
236 |
apply (rule_tac ?t1.0 = "$ ((%x. if x : free_tv A Un free_tv t then S x else TVar x) o (%x. if x : free_tv A then x else n + x)) t1" in has_type.LETI)
|
|
|
237 |
apply (drule_tac x = " (%x. if x : free_tv A Un free_tv t then S x else TVar x) o (%x. if x : free_tv A then x else n + x) " in spec)
|
|
|
238 |
apply (subst S'_A_eq_S'_alpha_A)
|
|
|
239 |
apply assumption
|
|
|
240 |
apply (subst S_o_alpha_typ)
|
|
|
241 |
apply (subst gen_subst_commutes)
|
|
|
242 |
apply (rule subset_antisym)
|
|
|
243 |
apply (rule subsetI)
|
|
|
244 |
apply (erule IntE)
|
|
|
245 |
apply (drule free_tv_S' [THEN subsetD])
|
|
|
246 |
apply (drule free_tv_alpha [THEN subsetD])
|
|
|
247 |
apply (simp del: full_SetCompr_eq)
|
|
|
248 |
apply (erule exE)
|
|
|
249 |
apply (hypsubst)
|
|
|
250 |
apply (subgoal_tac "new_tv (n + y) ($ S A) ")
|
|
|
251 |
apply (subgoal_tac "new_tv (n + y) ($ S t) ")
|
|
|
252 |
apply (subgoal_tac "new_tv (n + y) A")
|
|
|
253 |
apply (subgoal_tac "new_tv (n + y) t")
|
|
|
254 |
apply (drule new_tv_not_free_tv)+
|
|
|
255 |
apply fast
|
|
|
256 |
apply (rule new_tv_le) prefer 2 apply assumption apply simp
|
|
|
257 |
apply (rule new_tv_le) prefer 2 apply assumption apply simp
|
|
|
258 |
apply (rule new_tv_le) prefer 2 apply assumption apply simp
|
|
|
259 |
apply (rule new_tv_le) prefer 2 apply assumption apply simp
|
|
|
260 |
apply fast
|
|
|
261 |
apply (rule has_type_le_env)
|
|
|
262 |
apply (drule spec)
|
|
|
263 |
apply (drule spec)
|
|
|
264 |
apply assumption
|
|
|
265 |
apply (rule app_subst_Cons [THEN subst])
|
|
|
266 |
apply (rule S_compatible_le_scheme_lists)
|
|
|
267 |
apply (simp (no_asm_simp))
|
|
|
268 |
done
|
|
|
269 |
|
|
1300
|
270 |
|
|
|
271 |
end
|