| author | wenzelm | 
| Wed, 08 Mar 2000 17:48:31 +0100 | |
| changeset 8364 | 0eb9ee70c8f8 | 
| parent 7499 | 23e090051cb8 | 
| child 11232 | 558a4feebb04 | 
| permissions | -rw-r--r-- | 
| 1300 | 1  | 
(* Title: HOL/MiniML/W.ML  | 
2  | 
ID: $Id$  | 
|
3  | 
Author: Dieter Nazareth and Tobias Nipkow  | 
|
4  | 
Copyright 1995 TU Muenchen  | 
|
5  | 
||
6  | 
Correctness and completeness of type inference algorithm W  | 
|
7  | 
*)  | 
|
8  | 
||
| 5348 | 9  | 
Addsimps [Suc_le_lessD]; Delsimps [less_imp_le]; (*the combination loops*)  | 
| 1300 | 10  | 
|
| 6141 | 11  | 
val has_type_casesE =  | 
12  | 
map has_type.mk_cases  | 
|
13  | 
[" A |- Var n :: t",  | 
|
14  | 
" A |- Abs e :: t",  | 
|
15  | 
"A |- App e1 e2 ::t",  | 
|
16  | 
"A |- LET e1 e2 ::t" ];  | 
|
| 1300 | 17  | 
|
18  | 
(* the resulting type variable is always greater or equal than the given one *)  | 
|
| 6141 | 19  | 
Goal "!A n S t m. W e A n = Some (S,t,m) --> n<=m";  | 
| 5184 | 20  | 
by (induct_tac "e" 1);  | 
| 1300 | 21  | 
(* case Var(n) *)  | 
| 4686 | 22  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 1300 | 23  | 
(* case Abs e *)  | 
| 4089 | 24  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 1300 | 25  | 
by (fast_tac (HOL_cs addDs [Suc_leD]) 1);  | 
26  | 
(* case App e1 e2 *)  | 
|
| 4089 | 27  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 4423 | 28  | 
by (blast_tac (claset() addIs [le_SucI,le_trans]) 1);  | 
| 2525 | 29  | 
(* case LET e1 e2 *)  | 
| 4089 | 30  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 4423 | 31  | 
by (blast_tac (claset() addIs [le_trans]) 1);  | 
| 1486 | 32  | 
qed_spec_mp "W_var_ge";  | 
| 1300 | 33  | 
|
34  | 
Addsimps [W_var_ge];  | 
|
35  | 
||
| 6141 | 36  | 
Goal "Some (S,t,m) = W e A n ==> n<=m";  | 
| 4089 | 37  | 
by (asm_full_simp_tac (simpset() addsimps [eq_sym_conv]) 1);  | 
| 1300 | 38  | 
qed "W_var_geD";  | 
39  | 
||
| 5118 | 40  | 
Goal "new_tv n A ==> Some (S,t,m) = W e A n ==> new_tv m A";  | 
| 2525 | 41  | 
by (dtac W_var_geD 1);  | 
42  | 
by (rtac new_scheme_list_le 1);  | 
|
| 3018 | 43  | 
by (assume_tac 1);  | 
44  | 
by (assume_tac 1);  | 
|
| 2525 | 45  | 
qed "new_tv_compatible_W";  | 
| 1300 | 46  | 
|
| 5118 | 47  | 
Goal "new_tv n sch --> new_tv (n + (min_new_bound_tv sch)) (bound_typ_inst (%b. TVar (b + n)) sch)";  | 
| 5184 | 48  | 
by (induct_tac "sch" 1);  | 
| 4727 | 49  | 
by (Asm_full_simp_tac 1);  | 
50  | 
by (asm_full_simp_tac (simpset() addsimps [add_commute]) 1);  | 
|
| 2525 | 51  | 
by (strip_tac 1);  | 
52  | 
by (Asm_full_simp_tac 1);  | 
|
53  | 
by (etac conjE 1);  | 
|
54  | 
by (rtac conjI 1);  | 
|
| 4727 | 55  | 
by (rtac new_tv_le 1);  | 
56  | 
by (assume_tac 2);  | 
|
57  | 
by (rtac add_le_mono 1);  | 
|
58  | 
by (Simp_tac 1);  | 
|
59  | 
by (simp_tac (simpset() addsimps [max_def]) 1);  | 
|
| 2525 | 60  | 
by (rtac new_tv_le 1);  | 
| 4727 | 61  | 
by (assume_tac 2);  | 
| 2525 | 62  | 
by (rtac add_le_mono 1);  | 
| 4727 | 63  | 
by (Simp_tac 1);  | 
| 4686 | 64  | 
by (simp_tac (simpset() addsimps [max_def]) 1);  | 
| 2525 | 65  | 
qed_spec_mp "new_tv_bound_typ_inst_sch";  | 
66  | 
||
67  | 
Addsimps [new_tv_bound_typ_inst_sch];  | 
|
| 1300 | 68  | 
|
69  | 
(* resulting type variable is new *)  | 
|
| 6141 | 70  | 
Goal "!n A S t m. new_tv n A --> W e A n = Some (S,t,m) --> \  | 
| 2525 | 71  | 
\ new_tv m S & new_tv m t";  | 
| 5184 | 72  | 
by (induct_tac "e" 1);  | 
| 1300 | 73  | 
(* case Var n *)  | 
| 4686 | 74  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 2525 | 75  | 
by (strip_tac 1);  | 
76  | 
by (dtac new_tv_nth_nat_A 1);  | 
|
| 3018 | 77  | 
by (assume_tac 1);  | 
| 4033 | 78  | 
by (Asm_simp_tac 1);  | 
| 1300 | 79  | 
(* case Abs e *)  | 
| 4089 | 80  | 
by (simp_tac (simpset() addsimps [new_tv_subst,new_tv_Suc_list]  | 
| 4072 | 81  | 
addsplits [split_option_bind]) 1);  | 
| 1300 | 82  | 
by (strip_tac 1);  | 
83  | 
by (eres_inst_tac [("x","Suc n")] allE 1);
 | 
|
| 2525 | 84  | 
by (eres_inst_tac [("x","(FVar n)#A")] allE 1);
 | 
| 4089 | 85  | 
by (fast_tac (HOL_cs addss (simpset()  | 
| 1465 | 86  | 
addsimps [new_tv_subst,new_tv_Suc_list])) 1);  | 
| 1300 | 87  | 
(* case App e1 e2 *)  | 
| 4089 | 88  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 1300 | 89  | 
by (strip_tac 1);  | 
| 4033 | 90  | 
by (rename_tac "S1 t1 n1 S2 t2 n2 S3" 1);  | 
| 1300 | 91  | 
by (eres_inst_tac [("x","n")] allE 1);
 | 
| 2525 | 92  | 
by (eres_inst_tac [("x","A")] allE 1);
 | 
| 4033 | 93  | 
by (eres_inst_tac [("x","S1")] allE 1);
 | 
94  | 
by (eres_inst_tac [("x","t1")] allE 1);
 | 
|
| 2525 | 95  | 
by (eres_inst_tac [("x","n1")] allE 1);
 | 
96  | 
by (eres_inst_tac [("x","n1")] allE 1);
 | 
|
| 4089 | 97  | 
by (asm_full_simp_tac (simpset() addsimps [eq_sym_conv] delsimps all_simps) 1);  | 
| 4033 | 98  | 
by (eres_inst_tac [("x","$S1 A")] allE 1);
 | 
99  | 
by (eres_inst_tac [("x","S2")] allE 1);
 | 
|
100  | 
by (eres_inst_tac [("x","t2")] allE 1);
 | 
|
| 2525 | 101  | 
by (eres_inst_tac [("x","n2")] allE 1);
 | 
| 4089 | 102  | 
by ( asm_full_simp_tac (simpset() addsimps [o_def,rotate_Some]) 1);  | 
| 1300 | 103  | 
by (rtac conjI 1);  | 
104  | 
by (rtac new_tv_subst_comp_2 1);  | 
|
105  | 
by (rtac new_tv_subst_comp_2 1);  | 
|
| 2525 | 106  | 
by (rtac (lessI RS less_imp_le RS new_tv_le) 1);  | 
107  | 
by (res_inst_tac [("n","n1")] new_tv_subst_le 1); 
 | 
|
| 4089 | 108  | 
by (asm_full_simp_tac (simpset() addsimps [rotate_Some]) 1);  | 
| 1300 | 109  | 
by (Asm_simp_tac 1);  | 
110  | 
by (fast_tac (HOL_cs addDs [W_var_geD] addIs  | 
|
| 2525 | 111  | 
[new_scheme_list_le,new_tv_subst_scheme_list,lessI RS less_imp_le RS new_tv_subst_le])  | 
| 1300 | 112  | 
1);  | 
| 1465 | 113  | 
by (etac (sym RS mgu_new) 1);  | 
| 2525 | 114  | 
by (best_tac (HOL_cs addDs [W_var_geD] addIs [new_tv_subst_te,new_scheme_list_le,  | 
115  | 
new_tv_subst_scheme_list,lessI RS less_imp_le RS new_tv_le,lessI RS less_imp_le RS  | 
|
116  | 
new_tv_subst_le,new_tv_le]) 1);  | 
|
117  | 
by (fast_tac (HOL_cs addDs [W_var_geD] addIs  | 
|
118  | 
[new_scheme_list_le,new_tv_subst_scheme_list,new_tv_le]  | 
|
| 4089 | 119  | 
addss (simpset())) 1);  | 
| 1465 | 120  | 
by (rtac (lessI RS new_tv_subst_var) 1);  | 
121  | 
by (etac (sym RS mgu_new) 1);  | 
|
| 1925 | 122  | 
by (best_tac (HOL_cs addSIs [lessI RS less_imp_le RS new_tv_le,new_tv_subst_te]  | 
| 2525 | 123  | 
addDs [W_var_geD] addIs  | 
124  | 
[new_scheme_list_le,new_tv_subst_scheme_list,lessI RS less_imp_le RS  | 
|
| 4089 | 125  | 
new_tv_subst_le,new_tv_le] addss simpset()) 1);  | 
| 2525 | 126  | 
by (fast_tac (HOL_cs addDs [W_var_geD] addIs  | 
127  | 
[new_scheme_list_le,new_tv_subst_scheme_list,new_tv_le]  | 
|
| 4089 | 128  | 
addss (simpset())) 1);  | 
| 4033 | 129  | 
(* 41: case LET e1 e2 *)  | 
| 4089 | 130  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 2525 | 131  | 
by (strip_tac 1);  | 
| 4423 | 132  | 
by (EVERY1[etac allE,etac allE,etac allE,etac allE,etac allE,mp_tac,mp_tac]);  | 
| 2525 | 133  | 
by (etac conjE 1);  | 
| 4423 | 134  | 
by (EVERY[etac allE 1,etac allE 1,etac allE 1,etac allE 1,etac allE 1,  | 
| 4033 | 135  | 
etac impE 1, mp_tac 2]);  | 
136  | 
by (SELECT_GOAL(rewtac new_tv_def)1);  | 
|
137  | 
by (Asm_simp_tac 1);  | 
|
138  | 
by (REPEAT(dtac W_var_ge 1));  | 
|
139  | 
by (rtac allI 1);  | 
|
140  | 
by (strip_tac 1);  | 
|
141  | 
by (SELECT_GOAL(rewtac free_tv_subst) 1);  | 
|
142  | 
by (dtac (free_tv_app_subst_scheme_list RS subsetD) 1);  | 
|
| 4089 | 143  | 
by (best_tac (claset() addEs [less_le_trans]) 1);  | 
| 2525 | 144  | 
by (etac conjE 1);  | 
145  | 
by (rtac conjI 1);  | 
|
| 
6540
 
eaf90f6806df
Proof mods due to eta contraction during rewriting.
 
nipkow 
parents: 
6141 
diff
changeset
 | 
146  | 
by (SELECT_GOAL(rewtac o_def)1);  | 
| 2525 | 147  | 
by (rtac new_tv_subst_comp_2 1);  | 
| 4033 | 148  | 
by (etac (W_var_ge RS new_tv_subst_le) 1);  | 
| 3018 | 149  | 
by (assume_tac 1);  | 
150  | 
by (assume_tac 1);  | 
|
151  | 
by (assume_tac 1);  | 
|
| 1486 | 152  | 
qed_spec_mp "new_tv_W";  | 
| 1300 | 153  | 
|
| 5118 | 154  | 
Goal "(v ~: free_tv sch) --> (v : free_tv (bound_typ_inst (TVar o S) sch)) --> (? x. v = S x)";  | 
| 5184 | 155  | 
by (induct_tac "sch" 1);  | 
| 2525 | 156  | 
by (Asm_full_simp_tac 1);  | 
157  | 
by (Asm_full_simp_tac 1);  | 
|
158  | 
by (strip_tac 1);  | 
|
159  | 
by (rtac exI 1);  | 
|
160  | 
by (rtac refl 1);  | 
|
161  | 
by (Asm_full_simp_tac 1);  | 
|
162  | 
qed_spec_mp "free_tv_bound_typ_inst1";  | 
|
163  | 
||
164  | 
Addsimps [free_tv_bound_typ_inst1];  | 
|
| 1300 | 165  | 
|
| 6141 | 166  | 
Goal "!n A S t m v. W e A n = Some (S,t,m) --> \  | 
| 2525 | 167  | 
\ (v:free_tv S | v:free_tv t) --> v<n --> v:free_tv A";  | 
| 5184 | 168  | 
by (induct_tac "e" 1);  | 
| 1300 | 169  | 
(* case Var n *)  | 
| 4089 | 170  | 
by (simp_tac (simpset() addsimps  | 
| 4686 | 171  | 
[free_tv_subst] addsplits [split_option_bind]) 1);  | 
| 2525 | 172  | 
by (strip_tac 1);  | 
| 4502 | 173  | 
by (case_tac "v : free_tv (A!nat)" 1);  | 
| 2525 | 174  | 
by (Asm_full_simp_tac 1);  | 
175  | 
by (dtac free_tv_bound_typ_inst1 1);  | 
|
| 4089 | 176  | 
by (simp_tac (simpset() addsimps [o_def]) 1);  | 
| 2525 | 177  | 
by (etac exE 1);  | 
178  | 
by (rotate_tac 3 1);  | 
|
179  | 
by (Asm_full_simp_tac 1);  | 
|
| 1300 | 180  | 
(* case Abs e *)  | 
| 4089 | 181  | 
by (asm_full_simp_tac (simpset() addsimps  | 
| 4072 | 182  | 
[free_tv_subst] addsplits [split_option_bind] delsimps all_simps) 1);  | 
| 1300 | 183  | 
by (strip_tac 1);  | 
| 2525 | 184  | 
by (rename_tac "S t n1 S1 t1 m v" 1);  | 
| 1300 | 185  | 
by (eres_inst_tac [("x","Suc n")] allE 1);
 | 
| 2525 | 186  | 
by (eres_inst_tac [("x","FVar n # A")] allE 1);
 | 
187  | 
by (eres_inst_tac [("x","S")] allE 1);
 | 
|
| 1300 | 188  | 
by (eres_inst_tac [("x","t")] allE 1);
 | 
| 2525 | 189  | 
by (eres_inst_tac [("x","n1")] allE 1);
 | 
| 1300 | 190  | 
by (eres_inst_tac [("x","v")] allE 1);
 | 
| 2525 | 191  | 
by (best_tac (HOL_cs addIs [cod_app_subst]  | 
| 4089 | 192  | 
addss (simpset() addsimps [less_Suc_eq])) 1);  | 
| 1300 | 193  | 
(* case App e1 e2 *)  | 
| 4089 | 194  | 
by (simp_tac (simpset() addsplits [split_option_bind] delsimps all_simps) 1);  | 
| 1300 | 195  | 
by (strip_tac 1);  | 
| 2525 | 196  | 
by (rename_tac "S t n1 S1 t1 n2 S2 S3 t2 m v" 1);  | 
| 1300 | 197  | 
by (eres_inst_tac [("x","n")] allE 1);
 | 
| 2525 | 198  | 
by (eres_inst_tac [("x","A")] allE 1);
 | 
199  | 
by (eres_inst_tac [("x","S")] allE 1);
 | 
|
| 1300 | 200  | 
by (eres_inst_tac [("x","t")] allE 1);
 | 
| 2525 | 201  | 
by (eres_inst_tac [("x","n1")] allE 1);
 | 
202  | 
by (eres_inst_tac [("x","n1")] allE 1);
 | 
|
| 1300 | 203  | 
by (eres_inst_tac [("x","v")] allE 1);
 | 
204  | 
(* second case *)  | 
|
| 2525 | 205  | 
by (eres_inst_tac [("x","$ S A")] allE 1);
 | 
206  | 
by (eres_inst_tac [("x","S1")] allE 1);
 | 
|
207  | 
by (eres_inst_tac [("x","t1")] allE 1);
 | 
|
208  | 
by (eres_inst_tac [("x","n2")] allE 1);
 | 
|
| 1300 | 209  | 
by (eres_inst_tac [("x","v")] allE 1);
 | 
210  | 
by (safe_tac (empty_cs addSIs [conjI,impI] addSEs [conjE]) );  | 
|
| 4089 | 211  | 
by (asm_full_simp_tac (simpset() addsimps [rotate_Some,o_def]) 1);  | 
| 1465 | 212  | 
by (dtac W_var_geD 1);  | 
213  | 
by (dtac W_var_geD 1);  | 
|
| 7499 | 214  | 
by ( (ftac less_le_trans 1) THEN (assume_tac 1) );  | 
| 1300 | 215  | 
by (fast_tac (HOL_cs addDs [free_tv_comp_subst RS subsetD,sym RS mgu_free,  | 
| 2525 | 216  | 
codD,free_tv_app_subst_te RS subsetD,free_tv_app_subst_scheme_list RS subsetD,  | 
| 1300 | 217  | 
less_le_trans,less_not_refl2,subsetD]  | 
218  | 
addEs [UnE]  | 
|
| 4089 | 219  | 
addss simpset()) 1);  | 
| 1300 | 220  | 
by (Asm_full_simp_tac 1);  | 
| 1465 | 221  | 
by (dtac (sym RS W_var_geD) 1);  | 
222  | 
by (dtac (sym RS W_var_geD) 1);  | 
|
| 7499 | 223  | 
by ( (ftac less_le_trans 1) THEN (assume_tac 1) );  | 
| 1300 | 224  | 
by (fast_tac (HOL_cs addDs [mgu_free, codD,free_tv_subst_var RS subsetD,  | 
| 2525 | 225  | 
free_tv_app_subst_te RS subsetD,free_tv_app_subst_scheme_list RS subsetD,  | 
226  | 
less_le_trans,subsetD]  | 
|
227  | 
addEs [UnE]  | 
|
| 
5655
 
afd75136b236
Mods because of: Installed trans_tac in solver of simpset().
 
nipkow 
parents: 
5348 
diff
changeset
 | 
228  | 
addss (simpset() setSolver unsafe_solver)) 1);  | 
| 2525 | 229  | 
(* LET e1 e2 *)  | 
| 4089 | 230  | 
by (simp_tac (simpset() addsplits [split_option_bind] delsimps all_simps) 1);  | 
| 2525 | 231  | 
by (strip_tac 1);  | 
232  | 
by (rename_tac "nat A S1 t1 n2 S2 t2 m2 S t m v" 1);  | 
|
233  | 
by (eres_inst_tac [("x","nat")] allE 1);
 | 
|
234  | 
by (eres_inst_tac [("x","A")] allE 1);
 | 
|
235  | 
by (eres_inst_tac [("x","S1")] allE 1);
 | 
|
236  | 
by (eres_inst_tac [("x","t1")] allE 1);
 | 
|
237  | 
by (rotate_tac 1 1);  | 
|
238  | 
by (eres_inst_tac [("x","n2")] allE 1);
 | 
|
239  | 
by (rotate_tac 4 1);  | 
|
240  | 
by (eres_inst_tac [("x","v")] allE 1);
 | 
|
241  | 
by (mp_tac 1);  | 
|
242  | 
by (EVERY1 [etac allE,etac allE,etac allE,etac allE,etac allE,eres_inst_tac [("x","v")] allE]);
 | 
|
243  | 
by (mp_tac 1);  | 
|
244  | 
by (Asm_full_simp_tac 1);  | 
|
245  | 
by (rtac conjI 1);  | 
|
| 4089 | 246  | 
by (fast_tac (claset() addSDs [codD,free_tv_app_subst_scheme_list RS subsetD,free_tv_o_subst RS subsetD,W_var_ge]  | 
| 2525 | 247  | 
addDs [less_le_trans]) 1);  | 
| 4089 | 248  | 
by (fast_tac (claset() addSDs [codD,free_tv_app_subst_scheme_list RS subsetD,W_var_ge]  | 
| 2525 | 249  | 
addDs [less_le_trans]) 1);  | 
| 1486 | 250  | 
qed_spec_mp "free_tv_W";  | 
| 1300 | 251  | 
|
| 5118 | 252  | 
Goal "(!x. x : A --> x ~: B) ==> A Int B = {}";
 | 
| 2525 | 253  | 
by (Fast_tac 1);  | 
| 2625 | 254  | 
val weaken_A_Int_B_eq_empty = result();  | 
| 2525 | 255  | 
|
| 5118 | 256  | 
Goal "x ~: A | x : B ==> x ~: A - B";  | 
| 2525 | 257  | 
by (Fast_tac 1);  | 
| 2625 | 258  | 
val weaken_not_elem_A_minus_B = result();  | 
| 2525 | 259  | 
|
260  | 
(* correctness of W with respect to has_type *)  | 
|
| 6141 | 261  | 
Goal "!A S t m n . new_tv n A --> Some (S,t,m) = W e A n --> $S A |- e :: t";  | 
| 5184 | 262  | 
by (induct_tac "e" 1);  | 
| 2525 | 263  | 
(* case Var n *)  | 
| 4686 | 264  | 
by (Asm_full_simp_tac 1);  | 
| 2525 | 265  | 
by (strip_tac 1);  | 
266  | 
by (rtac has_type.VarI 1);  | 
|
267  | 
by (Simp_tac 1);  | 
|
| 4089 | 268  | 
by (simp_tac (simpset() addsimps [is_bound_typ_instance]) 1);  | 
| 2525 | 269  | 
by (rtac exI 1);  | 
270  | 
by (rtac refl 1);  | 
|
271  | 
(* case Abs e *)  | 
|
| 4089 | 272  | 
by (asm_full_simp_tac (simpset() addsimps [app_subst_list]  | 
| 4072 | 273  | 
addsplits [split_option_bind]) 1);  | 
| 2525 | 274  | 
by (strip_tac 1);  | 
275  | 
by (eres_inst_tac [("x","(mk_scheme (TVar n)) # A")] allE 1);
 | 
|
276  | 
by (Asm_full_simp_tac 1);  | 
|
277  | 
by (rtac has_type.AbsI 1);  | 
|
278  | 
by (dtac (le_refl RS le_SucI RS new_scheme_list_le) 1);  | 
|
| 3018 | 279  | 
by (dtac sym 1);  | 
| 2525 | 280  | 
by (REPEAT (etac allE 1));  | 
281  | 
by (etac impE 1);  | 
|
282  | 
by (mp_tac 2);  | 
|
283  | 
by (Asm_simp_tac 1);  | 
|
| 3018 | 284  | 
by (assume_tac 1);  | 
| 2525 | 285  | 
(* case App e1 e2 *)  | 
| 4089 | 286  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 2525 | 287  | 
by (strip_tac 1);  | 
288  | 
by (rename_tac "S1 t1 n1 S2 t2 n2 S3" 1);  | 
|
289  | 
by (res_inst_tac [("t2.0","$ S3 t2")] has_type.AppI 1);
 | 
|
290  | 
by (res_inst_tac [("S1","S3")] (app_subst_TVar RS subst) 1);
 | 
|
291  | 
by (rtac (app_subst_Fun RS subst) 1);  | 
|
292  | 
by (res_inst_tac [("t","$S3 (t2 -> (TVar n2))"),("s","$S3 ($S2 t1)")] subst 1);
 | 
|
293  | 
by (Asm_full_simp_tac 1);  | 
|
| 
6540
 
eaf90f6806df
Proof mods due to eta contraction during rewriting.
 
nipkow 
parents: 
6141 
diff
changeset
 | 
294  | 
by (simp_tac (HOL_ss addsimps [subst_comp_scheme_list RS sym,o_def]) 1);  | 
| 2525 | 295  | 
by ((rtac (has_type_cl_sub RS spec) 1) THEN (rtac (has_type_cl_sub RS spec) 1));  | 
| 4089 | 296  | 
by (asm_full_simp_tac (simpset() addsimps [eq_sym_conv]) 1);  | 
297  | 
by (asm_full_simp_tac (simpset() addsimps [subst_comp_scheme_list RS sym,o_def,has_type_cl_sub,eq_sym_conv]) 1);  | 
|
| 2525 | 298  | 
by (rtac (has_type_cl_sub RS spec) 1);  | 
| 7499 | 299  | 
by (ftac new_tv_W 1);  | 
| 3018 | 300  | 
by (assume_tac 1);  | 
| 2525 | 301  | 
by (dtac conjunct1 1);  | 
302  | 
by (dtac conjunct1 1);  | 
|
| 7499 | 303  | 
by (ftac new_tv_subst_scheme_list 1);  | 
| 2525 | 304  | 
by (rtac new_scheme_list_le 1);  | 
305  | 
by (rtac W_var_ge 1);  | 
|
| 3018 | 306  | 
by (assume_tac 1);  | 
307  | 
by (assume_tac 1);  | 
|
| 2525 | 308  | 
by (etac thin_rl 1);  | 
309  | 
by (REPEAT (etac allE 1));  | 
|
| 3018 | 310  | 
by (dtac sym 1);  | 
311  | 
by (dtac sym 1);  | 
|
| 2525 | 312  | 
by (etac thin_rl 1);  | 
313  | 
by (etac thin_rl 1);  | 
|
314  | 
by (mp_tac 1);  | 
|
315  | 
by (mp_tac 1);  | 
|
| 3018 | 316  | 
by (assume_tac 1);  | 
| 2525 | 317  | 
(* case Let e1 e2 *)  | 
| 4089 | 318  | 
by (simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
| 2525 | 319  | 
by (strip_tac 1);  | 
320  | 
by (rename_tac "w q m1 S1 t1 m2 S2 t n2" 1);  | 
|
321  | 
by (res_inst_tac [("t1.0","$ S2 t1")] has_type.LETI 1);
 | 
|
| 4089 | 322  | 
by (simp_tac (simpset() addsimps [o_def]) 1);  | 
| 2525 | 323  | 
by (simp_tac (HOL_ss addsimps [subst_comp_scheme_list RS sym]) 1);  | 
324  | 
by (rtac (has_type_cl_sub RS spec) 1);  | 
|
325  | 
by (dres_inst_tac [("x","A")] spec 1);
 | 
|
326  | 
by (dres_inst_tac [("x","S1")] spec 1);
 | 
|
327  | 
by (dres_inst_tac [("x","t1")] spec 1);
 | 
|
328  | 
by (dres_inst_tac [("x","m2")] spec 1);
 | 
|
329  | 
by (rotate_tac 4 1);  | 
|
330  | 
by (dres_inst_tac [("x","m1")] spec 1);
 | 
|
331  | 
by (mp_tac 1);  | 
|
| 4089 | 332  | 
by (asm_full_simp_tac (simpset() addsimps [eq_sym_conv]) 1);  | 
333  | 
by (simp_tac (simpset() addsimps [o_def]) 1);  | 
|
| 2525 | 334  | 
by (simp_tac (HOL_ss addsimps [subst_comp_scheme_list RS sym]) 1);  | 
335  | 
by (rtac (gen_subst_commutes RS sym RS subst) 1);  | 
|
336  | 
by (rtac (app_subst_Cons RS subst) 2);  | 
|
337  | 
by (etac thin_rl 2);  | 
|
338  | 
by (dres_inst_tac [("x","gen ($S1 A) t1 # $ S1 A")] spec 2);
 | 
|
339  | 
by (dres_inst_tac [("x","S2")] spec 2);
 | 
|
340  | 
by (dres_inst_tac [("x","t")] spec 2);
 | 
|
341  | 
by (dres_inst_tac [("x","n2")] spec 2);
 | 
|
342  | 
by (dres_inst_tac [("x","m2")] spec 2);
 | 
|
| 7499 | 343  | 
by (ftac new_tv_W 2);  | 
| 3018 | 344  | 
by (assume_tac 2);  | 
| 2525 | 345  | 
by (dtac conjunct1 2);  | 
346  | 
by (dtac conjunct1 2);  | 
|
| 7499 | 347  | 
by (ftac new_tv_subst_scheme_list 2);  | 
| 2525 | 348  | 
by (rtac new_scheme_list_le 2);  | 
349  | 
by (rtac W_var_ge 2);  | 
|
| 3018 | 350  | 
by (assume_tac 2);  | 
351  | 
by (assume_tac 2);  | 
|
| 2525 | 352  | 
by (etac impE 2);  | 
353  | 
by (res_inst_tac [("A","$ S1 A")] new_tv_only_depends_on_free_tv_scheme_list 2);
 | 
|
354  | 
by (Simp_tac 2);  | 
|
355  | 
by (Fast_tac 2);  | 
|
| 3018 | 356  | 
by (assume_tac 2);  | 
| 2525 | 357  | 
by (Asm_full_simp_tac 2);  | 
358  | 
by (rtac weaken_A_Int_B_eq_empty 1);  | 
|
359  | 
by (rtac allI 1);  | 
|
360  | 
by (strip_tac 1);  | 
|
361  | 
by (rtac weaken_not_elem_A_minus_B 1);  | 
|
362  | 
by (case_tac "x < m2" 1);  | 
|
363  | 
by (rtac disjI2 1);  | 
|
364  | 
by (rtac (free_tv_gen_cons RS subst) 1);  | 
|
365  | 
by (rtac free_tv_W 1);  | 
|
| 3018 | 366  | 
by (assume_tac 1);  | 
| 2525 | 367  | 
by (Asm_full_simp_tac 1);  | 
| 3018 | 368  | 
by (assume_tac 1);  | 
| 2525 | 369  | 
by (rtac disjI1 1);  | 
370  | 
by (dtac new_tv_W 1);  | 
|
| 3018 | 371  | 
by (assume_tac 1);  | 
| 2525 | 372  | 
by (dtac conjunct2 1);  | 
373  | 
by (dtac conjunct2 1);  | 
|
374  | 
by (rtac new_tv_not_free_tv 1);  | 
|
375  | 
by (rtac new_tv_le 1);  | 
|
| 3018 | 376  | 
by (assume_tac 2);  | 
| 4089 | 377  | 
by (asm_full_simp_tac (simpset() addsimps [not_less_iff_le]) 1);  | 
| 2525 | 378  | 
qed_spec_mp "W_correct_lemma";  | 
379  | 
||
| 1300 | 380  | 
(* Completeness of W w.r.t. has_type *)  | 
| 6141 | 381  | 
Goal "!S' A t' n. $S' A |- e :: t' --> new_tv n A --> \  | 
| 2525 | 382  | 
\ (? S t. (? m. W e A n = Some (S,t,m)) & \  | 
383  | 
\ (? R. $S' A = $R ($S A) & t' = $R t))";  | 
|
| 5184 | 384  | 
by (induct_tac "e" 1);  | 
| 1300 | 385  | 
(* case Var n *)  | 
386  | 
by (strip_tac 1);  | 
|
| 4686 | 387  | 
by (simp_tac (simpset() addcongs [conj_cong]) 1);  | 
| 1300 | 388  | 
by (eresolve_tac has_type_casesE 1);  | 
| 4089 | 389  | 
by (asm_full_simp_tac (simpset() addsimps [is_bound_typ_instance]) 1);  | 
| 2525 | 390  | 
by (etac exE 1);  | 
391  | 
by (hyp_subst_tac 1);  | 
|
392  | 
by (rename_tac "S" 1);  | 
|
393  | 
by (res_inst_tac [("x","%x. (if x < n then S' x else S (x - n))")] exI 1);
 | 
|
394  | 
by (rtac conjI 1);  | 
|
| 1300 | 395  | 
by (Asm_simp_tac 1);  | 
| 4089 | 396  | 
by (asm_simp_tac (simpset() addsimps [(bound_typ_inst_composed_subst RS sym),new_tv_nth_nat_A,o_def,nth_subst]  | 
| 2525 | 397  | 
delsimps [bound_typ_inst_composed_subst]) 1);  | 
| 
2749
 
2f477a0e690d
Deleted steps made redundant by the stronger eq_assume_tac
 
paulson 
parents: 
2637 
diff
changeset
 | 
398  | 
(** LEVEL 12 **)  | 
| 1300 | 399  | 
(* case Abs e *)  | 
400  | 
by (strip_tac 1);  | 
|
401  | 
by (eresolve_tac has_type_casesE 1);  | 
|
| 3842 | 402  | 
by (eres_inst_tac [("x","%x. if x=n then t1 else (S' x)")] allE 1);
 | 
| 2525 | 403  | 
by (eres_inst_tac [("x","(FVar n)#A")] allE 1);
 | 
| 1300 | 404  | 
by (eres_inst_tac [("x","t2")] allE 1);
 | 
405  | 
by (eres_inst_tac [("x","Suc n")] allE 1);
 | 
|
| 
2749
 
2f477a0e690d
Deleted steps made redundant by the stronger eq_assume_tac
 
paulson 
parents: 
2637 
diff
changeset
 | 
406  | 
by (best_tac (HOL_cs addSDs [mk_scheme_injective]  | 
| 4089 | 407  | 
addss (simpset() addcongs [conj_cong]  | 
| 4072 | 408  | 
addsplits [split_option_bind])) 1);  | 
| 
2749
 
2f477a0e690d
Deleted steps made redundant by the stronger eq_assume_tac
 
paulson 
parents: 
2637 
diff
changeset
 | 
409  | 
(** LEVEL 19 **)  | 
| 1300 | 410  | 
|
411  | 
(* case App e1 e2 *)  | 
|
412  | 
by (strip_tac 1);  | 
|
413  | 
by (eresolve_tac has_type_casesE 1);  | 
|
| 2525 | 414  | 
by (eres_inst_tac [("x","S'")] allE 1);
 | 
415  | 
by (eres_inst_tac [("x","A")] allE 1);
 | 
|
| 1400 | 416  | 
by (eres_inst_tac [("x","t2 -> t'")] allE 1);
 | 
| 1300 | 417  | 
by (eres_inst_tac [("x","n")] allE 1);
 | 
418  | 
by (safe_tac HOL_cs);  | 
|
| 
2749
 
2f477a0e690d
Deleted steps made redundant by the stronger eq_assume_tac
 
paulson 
parents: 
2637 
diff
changeset
 | 
419  | 
(** LEVEL 26 **)  | 
| 2525 | 420  | 
by (eres_inst_tac [("x","R")] allE 1);
 | 
421  | 
by (eres_inst_tac [("x","$ S A")] allE 1);
 | 
|
| 1300 | 422  | 
by (eres_inst_tac [("x","t2")] allE 1);
 | 
423  | 
by (eres_inst_tac [("x","m")] allE 1);
 | 
|
424  | 
by (Asm_full_simp_tac 1);  | 
|
425  | 
by (safe_tac HOL_cs);  | 
|
426  | 
by (fast_tac (HOL_cs addIs [sym RS W_var_geD,new_tv_W RS  | 
|
| 2525 | 427  | 
conjunct1,new_scheme_list_le,new_tv_subst_scheme_list]) 1);  | 
| 
6540
 
eaf90f6806df
Proof mods due to eta contraction during rewriting.
 
nipkow 
parents: 
6141 
diff
changeset
 | 
428  | 
(** LEVEL 33 **)  | 
| 1300 | 429  | 
by (subgoal_tac  | 
| 3842 | 430  | 
"$ (%x. if x=ma then t' else (if x:(free_tv t - free_tv Sa) then R x \  | 
| 2525 | 431  | 
\ else Ra x)) ($ Sa t) = \  | 
| 3842 | 432  | 
\ $ (%x. if x=ma then t' else (if x:(free_tv t - free_tv Sa) then R x \  | 
| 2525 | 433  | 
\ else Ra x)) (ta -> (TVar ma))" 1);  | 
| 1300 | 434  | 
by (res_inst_tac [("t","$ (%x. if x = ma then t' else \
 | 
| 2525 | 435  | 
\ (if x:(free_tv t - free_tv Sa) then R x else Ra x)) ($ Sa t)"),  | 
436  | 
    ("s","($ Ra ta) -> t'")] ssubst 2);
 | 
|
| 4089 | 437  | 
by (asm_simp_tac (simpset() addsimps [subst_comp_te]) 2);  | 
| 1465 | 438  | 
by (rtac eq_free_eq_subst_te 2);  | 
| 1300 | 439  | 
by (strip_tac 2);  | 
440  | 
by (subgoal_tac "na ~=ma" 2);  | 
|
| 
2749
 
2f477a0e690d
Deleted steps made redundant by the stronger eq_assume_tac
 
paulson 
parents: 
2637 
diff
changeset
 | 
441  | 
by (best_tac (HOL_cs addDs [new_tv_W,sym RS W_var_geD,  | 
| 2525 | 442  | 
new_tv_not_free_tv,new_tv_le]) 3);  | 
443  | 
by (case_tac "na:free_tv Sa" 2);  | 
|
444  | 
(* n1 ~: free_tv S1 *)  | 
|
| 7499 | 445  | 
by (ftac not_free_impl_id 3);  | 
| 4686 | 446  | 
by (Asm_simp_tac 3);  | 
| 2525 | 447  | 
(* na : free_tv Sa *)  | 
448  | 
by (dres_inst_tac [("A1","$ S A")] (subst_comp_scheme_list RSN (2,trans)) 2);
 | 
|
449  | 
by (dtac eq_subst_scheme_list_eq_free 2);  | 
|
| 1300 | 450  | 
by (fast_tac (HOL_cs addIs [free_tv_W,free_tv_le_new_tv] addDs [new_tv_W]) 2);  | 
451  | 
by (Asm_simp_tac 2);  | 
|
| 2525 | 452  | 
by (case_tac "na:dom Sa" 2);  | 
453  | 
(* na ~: dom Sa *)  | 
|
| 4686 | 454  | 
by (asm_full_simp_tac (simpset() addsimps [dom_def]) 3);  | 
| 2525 | 455  | 
(* na : dom Sa *)  | 
| 1465 | 456  | 
by (rtac eq_free_eq_subst_te 2);  | 
| 1300 | 457  | 
by (strip_tac 2);  | 
458  | 
by (subgoal_tac "nb ~= ma" 2);  | 
|
| 7499 | 459  | 
by ((ftac new_tv_W 3) THEN (atac 3));  | 
| 1465 | 460  | 
by (etac conjE 3);  | 
| 2525 | 461  | 
by (dtac new_tv_subst_scheme_list 3);  | 
462  | 
by (fast_tac (HOL_cs addIs [new_scheme_list_le] addDs [sym RS W_var_geD]) 3);  | 
|
| 1300 | 463  | 
by (fast_tac (set_cs addDs [new_tv_W,new_tv_not_free_tv] addss  | 
| 4089 | 464  | 
(simpset() addsimps [cod_def,free_tv_subst])) 3);  | 
| 4686 | 465  | 
by (fast_tac (set_cs addss (simpset() addsimps [cod_def,free_tv_subst])) 2);  | 
| 1300 | 466  | 
by (Simp_tac 2);  | 
| 1465 | 467  | 
by (rtac eq_free_eq_subst_te 2);  | 
| 1300 | 468  | 
by (strip_tac 2 );  | 
469  | 
by (subgoal_tac "na ~= ma" 2);  | 
|
| 7499 | 470  | 
by ((ftac new_tv_W 3) THEN (atac 3));  | 
| 1465 | 471  | 
by (etac conjE 3);  | 
472  | 
by (dtac (sym RS W_var_geD) 3);  | 
|
| 2525 | 473  | 
by (fast_tac (HOL_cs addDs [new_scheme_list_le,new_tv_subst_scheme_list,new_tv_W,new_tv_not_free_tv]) 3);  | 
474  | 
by (case_tac "na: free_tv t - free_tv Sa" 2);  | 
|
475  | 
(* case na ~: free_tv t - free_tv Sa *)  | 
|
| 4686 | 476  | 
by (Asm_full_simp_tac 3);  | 
| 
2793
 
b30c41754c86
Modified proofs because simplifier does not eta-contract any longer.
 
nipkow 
parents: 
2779 
diff
changeset
 | 
477  | 
by (Fast_tac 3);  | 
| 2525 | 478  | 
(* case na : free_tv t - free_tv Sa *)  | 
| 4686 | 479  | 
by (Asm_full_simp_tac 2);  | 
| 2525 | 480  | 
by (dres_inst_tac [("A1","$ S A")] (subst_comp_scheme_list RSN (2,trans)) 2);
 | 
481  | 
by (dtac eq_subst_scheme_list_eq_free 2);  | 
|
| 1300 | 482  | 
by (fast_tac (HOL_cs addIs [free_tv_W,free_tv_le_new_tv] addDs [new_tv_W]) 2);  | 
| 
6540
 
eaf90f6806df
Proof mods due to eta contraction during rewriting.
 
nipkow 
parents: 
6141 
diff
changeset
 | 
483  | 
(** LEVEL 73 **)  | 
| 4089 | 484  | 
by (asm_full_simp_tac (simpset() addsimps [free_tv_subst,dom_def]) 2);  | 
485  | 
by (asm_simp_tac (simpset() addsplits [split_option_bind]) 1);  | 
|
| 1300 | 486  | 
by (safe_tac HOL_cs );  | 
| 2525 | 487  | 
by (dtac mgu_Some 1);  | 
| 4089 | 488  | 
by ( fast_tac (HOL_cs addss simpset()) 1);  | 
| 
6540
 
eaf90f6806df
Proof mods due to eta contraction during rewriting.
 
nipkow 
parents: 
6141 
diff
changeset
 | 
489  | 
(** LEVEL 78 *)  | 
| 1300 | 490  | 
by ((dtac mgu_mg 1) THEN (atac 1));  | 
| 1465 | 491  | 
by (etac exE 1);  | 
| 2525 | 492  | 
by (res_inst_tac [("x","Rb")] exI 1);
 | 
| 1465 | 493  | 
by (rtac conjI 1);  | 
| 1300 | 494  | 
by (dres_inst_tac [("x","ma")] fun_cong 2);
 | 
| 4089 | 495  | 
by ( asm_full_simp_tac (simpset() addsimps [eq_sym_conv]) 2);  | 
496  | 
by (simp_tac (simpset() addsimps [subst_comp_scheme_list]) 1);  | 
|
497  | 
by (simp_tac (simpset() addsimps [subst_comp_scheme_list RS sym]) 1);  | 
|
| 
2793
 
b30c41754c86
Modified proofs because simplifier does not eta-contract any longer.
 
nipkow 
parents: 
2779 
diff
changeset
 | 
498  | 
by (res_inst_tac [("A2","($ Sa ($ S A))")]
 | 
| 
 
b30c41754c86
Modified proofs because simplifier does not eta-contract any longer.
 
nipkow 
parents: 
2779 
diff
changeset
 | 
499  | 
((subst_comp_scheme_list RS sym) RSN (2,trans)) 1);  | 
| 4089 | 500  | 
by ( asm_full_simp_tac (simpset() addsimps [o_def,eq_sym_conv]) 1);  | 
| 7322 | 501  | 
by (dres_inst_tac [("s","Some ?X")] sym 1);
 | 
| 2525 | 502  | 
by (rtac eq_free_eq_subst_scheme_list 1);  | 
| 3018 | 503  | 
by ( safe_tac HOL_cs );  | 
| 1300 | 504  | 
by (subgoal_tac "ma ~= na" 1);  | 
| 7499 | 505  | 
by ((ftac new_tv_W 2) THEN (atac 2));  | 
| 1465 | 506  | 
by (etac conjE 2);  | 
| 2525 | 507  | 
by (dtac new_tv_subst_scheme_list 2);  | 
508  | 
by (fast_tac (HOL_cs addIs [new_scheme_list_le] addDs [sym RS W_var_geD]) 2);  | 
|
| 
2793
 
b30c41754c86
Modified proofs because simplifier does not eta-contract any longer.
 
nipkow 
parents: 
2779 
diff
changeset
 | 
509  | 
by (forw_inst_tac [("n","m")] new_tv_W 2  THEN  atac 2);
 | 
| 1465 | 510  | 
by (etac conjE 2);  | 
| 2525 | 511  | 
by (dtac (free_tv_app_subst_scheme_list RS subsetD) 2);  | 
| 
2793
 
b30c41754c86
Modified proofs because simplifier does not eta-contract any longer.
 
nipkow 
parents: 
2779 
diff
changeset
 | 
512  | 
by (fast_tac (set_cs addDs [sym RS W_var_geD,new_scheme_list_le,codD,  | 
| 1300 | 513  | 
new_tv_not_free_tv]) 2);  | 
| 2525 | 514  | 
by (case_tac "na: free_tv t - free_tv Sa" 1);  | 
515  | 
(* case na ~: free_tv t - free_tv Sa *)  | 
|
| 4686 | 516  | 
by (Asm_full_simp_tac 2);  | 
| 2525 | 517  | 
(* case na : free_tv t - free_tv Sa *)  | 
| 4686 | 518  | 
by (Asm_full_simp_tac 1);  | 
| 2525 | 519  | 
by (dtac (free_tv_app_subst_scheme_list RS subsetD) 1);  | 
520  | 
by (fast_tac (set_cs addDs [codD,subst_comp_scheme_list RSN (2,trans),  | 
|
| 4089 | 521  | 
eq_subst_scheme_list_eq_free] addss ((simpset() addsimps  | 
| 2525 | 522  | 
[free_tv_subst,dom_def]))) 1);  | 
| 
2083
 
b56425a385b9
Tidied some proofs: changed needed for de Morgan laws
 
paulson 
parents: 
2058 
diff
changeset
 | 
523  | 
by (Fast_tac 1);  | 
| 2525 | 524  | 
(* case Let e1 e2 *)  | 
525  | 
by (eresolve_tac has_type_casesE 1);  | 
|
526  | 
by (eres_inst_tac [("x","S'")] allE 1);
 | 
|
527  | 
by (eres_inst_tac [("x","A")] allE 1);
 | 
|
528  | 
by (eres_inst_tac [("x","t1")] allE 1);
 | 
|
529  | 
by (eres_inst_tac [("x","n")] allE 1);
 | 
|
530  | 
by (mp_tac 1);  | 
|
531  | 
by (mp_tac 1);  | 
|
532  | 
by (safe_tac HOL_cs);  | 
|
533  | 
by (Asm_simp_tac 1);  | 
|
534  | 
by (eres_inst_tac [("x","R")] allE 1);
 | 
|
535  | 
by (eres_inst_tac [("x","gen ($ S A) t # $ S A")] allE 1);
 | 
|
536  | 
by (eres_inst_tac [("x","t'")] allE 1);
 | 
|
537  | 
by (eres_inst_tac [("x","m")] allE 1);
 | 
|
538  | 
by (Asm_full_simp_tac 1);  | 
|
539  | 
by (dtac mp 1);  | 
|
540  | 
by (rtac has_type_le_env 1);  | 
|
| 3018 | 541  | 
by (assume_tac 1);  | 
| 2525 | 542  | 
by (Simp_tac 1);  | 
543  | 
by (rtac gen_bound_typ_instance 1);  | 
|
544  | 
by (dtac mp 1);  | 
|
| 7499 | 545  | 
by (ftac new_tv_compatible_W 1);  | 
| 2525 | 546  | 
by (rtac sym 1);  | 
| 3018 | 547  | 
by (assume_tac 1);  | 
| 4089 | 548  | 
by (fast_tac (claset() addDs [new_tv_compatible_gen,new_tv_subst_scheme_list,new_tv_W]) 1);  | 
| 2525 | 549  | 
by (safe_tac HOL_cs);  | 
550  | 
by (Asm_full_simp_tac 1);  | 
|
551  | 
by (res_inst_tac [("x","Ra")] exI 1);
 | 
|
| 4089 | 552  | 
by (simp_tac (simpset() addsimps [o_def,subst_comp_scheme_list RS sym]) 1);  | 
| 1525 | 553  | 
qed_spec_mp "W_complete_lemma";  | 
554  | 
||
| 6141 | 555  | 
Goal "[] |- e :: t' ==> (? S t. (? m. W e [] n = Some(S,t,m)) & \  | 
| 2525 | 556  | 
\ (? R. t' = $ R t))";  | 
| 3018 | 557  | 
by (cut_inst_tac [("A","[]"),("S'","id_subst"),("e","e"),("t'","t'")]
 | 
| 1525 | 558  | 
W_complete_lemma 1);  | 
| 3018 | 559  | 
by (ALLGOALS Asm_full_simp_tac);  | 
| 1525 | 560  | 
qed "W_complete";  |