| 437 |      1 | (*  Title: 	ZF/OrderArith.ML
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
 | 
|  |      4 |     Copyright   1994  University of Cambridge
 | 
|  |      5 | 
 | 
|  |      6 | Towards ordinal arithmetic 
 | 
|  |      7 | *)
 | 
|  |      8 | 
 | 
|  |      9 | open OrderArith;
 | 
|  |     10 | 
 | 
|  |     11 | 
 | 
|  |     12 | (**** Addition of relations -- disjoint sum ****)
 | 
|  |     13 | 
 | 
|  |     14 | (** Rewrite rules.  Can be used to obtain introduction rules **)
 | 
|  |     15 | 
 | 
|  |     16 | goalw OrderArith.thy [radd_def] 
 | 
|  |     17 |     "<Inl(a), Inr(b)> : radd(A,r,B,s)  <->  a:A & b:B";
 | 
|  |     18 | by (fast_tac sum_cs 1);
 | 
|  |     19 | val radd_Inl_Inr_iff = result();
 | 
|  |     20 | 
 | 
|  |     21 | goalw OrderArith.thy [radd_def] 
 | 
|  |     22 |     "<Inl(a'), Inl(a)> : radd(A,r,B,s)  <->  <a',a>:r & a':A & a:A";
 | 
|  |     23 | by (fast_tac sum_cs 1);
 | 
|  |     24 | val radd_Inl_iff = result();
 | 
|  |     25 | 
 | 
|  |     26 | goalw OrderArith.thy [radd_def] 
 | 
|  |     27 |     "<Inr(b'), Inr(b)> : radd(A,r,B,s) <->  <b',b>:s & b':B & b:B";
 | 
|  |     28 | by (fast_tac sum_cs 1);
 | 
|  |     29 | val radd_Inr_iff = result();
 | 
|  |     30 | 
 | 
|  |     31 | goalw OrderArith.thy [radd_def] 
 | 
|  |     32 |     "<Inr(b), Inl(a)> : radd(A,r,B,s) <->  False";
 | 
|  |     33 | by (fast_tac sum_cs 1);
 | 
|  |     34 | val radd_Inr_Inl_iff = result();
 | 
|  |     35 | 
 | 
|  |     36 | (** Elimination Rule **)
 | 
|  |     37 | 
 | 
|  |     38 | val major::prems = goalw OrderArith.thy [radd_def]
 | 
|  |     39 |     "[| <p',p> : radd(A,r,B,s);			\
 | 
|  |     40 | \       !!x y. [| p'=Inl(x); x:A; p=Inr(y); y:B |] ==> Q;	\
 | 
|  |     41 | \       !!x' x. [| p'=Inl(x'); p=Inl(x); <x',x>: r; x':A; x:A |] ==> Q;	\
 | 
|  |     42 | \       !!y' y. [| p'=Inr(y'); p=Inr(y); <y',y>: s; y':B; y:B |] ==> Q	\
 | 
|  |     43 | \    |] ==> Q";
 | 
|  |     44 | by (cut_facts_tac [major] 1);
 | 
|  |     45 | (*Split into the three cases*)
 | 
|  |     46 | by (REPEAT_FIRST
 | 
|  |     47 |     (eresolve_tac [CollectE, Pair_inject, conjE, exE, SigmaE, disjE]));
 | 
|  |     48 | (*Apply each premise to correct subgoal; can't just use fast_tac
 | 
|  |     49 |   because hyp_subst_tac would delete equalities too quickly*)
 | 
|  |     50 | by (EVERY (map (fn prem => 
 | 
|  |     51 | 		EVERY1 [rtac prem, assume_tac, REPEAT o fast_tac sum_cs])
 | 
|  |     52 | 	   prems));
 | 
|  |     53 | val raddE = result();
 | 
|  |     54 | 
 | 
|  |     55 | (** Type checking **)
 | 
|  |     56 | 
 | 
|  |     57 | goalw OrderArith.thy [radd_def] "radd(A,r,B,s) <= (A+B) * (A+B)";
 | 
|  |     58 | by (rtac Collect_subset 1);
 | 
|  |     59 | val radd_type = result();
 | 
|  |     60 | 
 | 
|  |     61 | val field_radd = standard (radd_type RS field_rel_subset);
 | 
|  |     62 | 
 | 
|  |     63 | (** Linearity **)
 | 
|  |     64 | 
 | 
|  |     65 | val sum_ss = ZF_ss addsimps [Pair_iff, InlI, InrI, Inl_iff, Inr_iff, 
 | 
|  |     66 | 			     Inl_Inr_iff, Inr_Inl_iff];
 | 
|  |     67 | 
 | 
|  |     68 | val radd_ss = sum_ss addsimps [radd_Inl_iff, radd_Inr_iff, 
 | 
|  |     69 | 			       radd_Inl_Inr_iff, radd_Inr_Inl_iff];
 | 
|  |     70 | 
 | 
|  |     71 | goalw OrderArith.thy [linear_def]
 | 
|  |     72 |     "!!r s. [| linear(A,r);  linear(B,s) |] ==> linear(A+B,radd(A,r,B,s))";
 | 
|  |     73 | by (REPEAT_FIRST (ares_tac [ballI] ORELSE' etac sumE));
 | 
|  |     74 | by (ALLGOALS (asm_simp_tac radd_ss));
 | 
|  |     75 | val linear_radd = result();
 | 
|  |     76 | 
 | 
|  |     77 | 
 | 
|  |     78 | (** Well-foundedness **)
 | 
|  |     79 | 
 | 
|  |     80 | goal OrderArith.thy
 | 
|  |     81 |     "!!r s. [| wf[A](r);  wf[B](s) |] ==> wf[A+B](radd(A,r,B,s))";
 | 
|  |     82 | by (rtac wf_onI2 1);
 | 
|  |     83 | by (subgoal_tac "ALL x:A. Inl(x): Ba" 1);
 | 
|  |     84 | (*Proving the lemma, which is needed twice!*)
 | 
| 662 |     85 | by (eres_inst_tac [("V", "y : A + B")] thin_rl 2);
 | 
| 437 |     86 | by (rtac ballI 2);
 | 
|  |     87 | by (eres_inst_tac [("r","r"),("a","x")] wf_on_induct 2 THEN assume_tac 2);
 | 
|  |     88 | by (etac (bspec RS mp) 2);
 | 
|  |     89 | by (fast_tac sum_cs 2);
 | 
|  |     90 | by (best_tac (sum_cs addSEs [raddE]) 2);
 | 
|  |     91 | (*Returning to main part of proof*)
 | 
|  |     92 | by (REPEAT_FIRST (eresolve_tac [sumE, ssubst]));
 | 
|  |     93 | by (best_tac sum_cs 1);
 | 
|  |     94 | by (eres_inst_tac [("r","s"),("a","ya")] wf_on_induct 1 THEN assume_tac 1);
 | 
|  |     95 | by (etac (bspec RS mp) 1);
 | 
|  |     96 | by (fast_tac sum_cs 1);
 | 
|  |     97 | by (best_tac (sum_cs addSEs [raddE]) 1);
 | 
|  |     98 | val wf_on_radd = result();
 | 
|  |     99 | 
 | 
|  |    100 | goal OrderArith.thy
 | 
|  |    101 |      "!!r s. [| wf(r);  wf(s) |] ==> wf(radd(field(r),r,field(s),s))";
 | 
|  |    102 | by (asm_full_simp_tac (ZF_ss addsimps [wf_iff_wf_on_field]) 1);
 | 
|  |    103 | by (rtac (field_radd RSN (2, wf_on_subset_A)) 1);
 | 
|  |    104 | by (REPEAT (ares_tac [wf_on_radd] 1));
 | 
|  |    105 | val wf_radd = result();
 | 
|  |    106 | 
 | 
|  |    107 | goal OrderArith.thy 
 | 
|  |    108 |     "!!r s. [| well_ord(A,r);  well_ord(B,s) |] ==> \
 | 
|  |    109 | \           well_ord(A+B, radd(A,r,B,s))";
 | 
|  |    110 | by (rtac well_ordI 1);
 | 
|  |    111 | by (asm_full_simp_tac (ZF_ss addsimps [well_ord_def, wf_on_radd]) 1);
 | 
|  |    112 | by (asm_full_simp_tac 
 | 
|  |    113 |     (ZF_ss addsimps [well_ord_def, tot_ord_def, linear_radd]) 1);
 | 
|  |    114 | val well_ord_radd = result();
 | 
|  |    115 | 
 | 
|  |    116 | 
 | 
|  |    117 | (**** Multiplication of relations -- lexicographic product ****)
 | 
|  |    118 | 
 | 
|  |    119 | (** Rewrite rule.  Can be used to obtain introduction rules **)
 | 
|  |    120 | 
 | 
|  |    121 | goalw OrderArith.thy [rmult_def] 
 | 
|  |    122 |     "!!r s. <<a',b'>, <a,b>> : rmult(A,r,B,s) <-> 	\
 | 
|  |    123 | \           (<a',a>: r  & a':A & a:A & b': B & b: B) | 	\
 | 
|  |    124 | \           (<b',b>: s  & a'=a & a:A & b': B & b: B)";
 | 
|  |    125 | by (fast_tac ZF_cs 1);
 | 
|  |    126 | val rmult_iff = result();
 | 
|  |    127 | 
 | 
|  |    128 | val major::prems = goal OrderArith.thy
 | 
|  |    129 |     "[| <<a',b'>, <a,b>> : rmult(A,r,B,s);		\
 | 
|  |    130 | \       [| <a',a>: r;  a':A;  a:A;  b':B;  b:B |] ==> Q;	\
 | 
|  |    131 | \       [| <b',b>: s;  a:A;  a'=a;  b':B;  b:B |] ==> Q	\
 | 
|  |    132 | \    |] ==> Q";
 | 
|  |    133 | by (rtac (major RS (rmult_iff RS iffD1) RS disjE) 1);
 | 
|  |    134 | by (DEPTH_SOLVE (eresolve_tac ([asm_rl, conjE] @ prems) 1));
 | 
|  |    135 | val rmultE = result();
 | 
|  |    136 | 
 | 
|  |    137 | (** Type checking **)
 | 
|  |    138 | 
 | 
|  |    139 | goalw OrderArith.thy [rmult_def] "rmult(A,r,B,s) <= (A*B) * (A*B)";
 | 
|  |    140 | by (rtac Collect_subset 1);
 | 
|  |    141 | val rmult_type = result();
 | 
|  |    142 | 
 | 
|  |    143 | val field_rmult = standard (rmult_type RS field_rel_subset);
 | 
|  |    144 | 
 | 
|  |    145 | (** Linearity **)
 | 
|  |    146 | 
 | 
|  |    147 | val [lina,linb] = goal OrderArith.thy
 | 
|  |    148 |     "[| linear(A,r);  linear(B,s) |] ==> linear(A*B,rmult(A,r,B,s))";
 | 
|  |    149 | by (rewtac linear_def);    (*Note! the premises are NOT rewritten*)
 | 
|  |    150 | by (REPEAT_FIRST (ares_tac [ballI] ORELSE' etac SigmaE));
 | 
|  |    151 | by (asm_simp_tac (ZF_ss addsimps [rmult_iff]) 1);
 | 
|  |    152 | by (res_inst_tac [("x","xa"), ("y","xb")] (lina RS linearE) 1);
 | 
|  |    153 | by (res_inst_tac [("x","ya"), ("y","yb")] (linb RS linearE) 4);
 | 
|  |    154 | by (REPEAT_SOME (fast_tac ZF_cs));
 | 
|  |    155 | val linear_rmult = result();
 | 
|  |    156 | 
 | 
|  |    157 | 
 | 
|  |    158 | (** Well-foundedness **)
 | 
|  |    159 | 
 | 
|  |    160 | goal OrderArith.thy
 | 
|  |    161 |     "!!r s. [| wf[A](r);  wf[B](s) |] ==> wf[A*B](rmult(A,r,B,s))";
 | 
|  |    162 | by (rtac wf_onI2 1);
 | 
|  |    163 | by (etac SigmaE 1);
 | 
|  |    164 | by (etac ssubst 1);
 | 
|  |    165 | by (subgoal_tac "ALL b:B. <x,b>: Ba" 1);
 | 
|  |    166 | by (fast_tac ZF_cs 1);
 | 
|  |    167 | by (eres_inst_tac [("a","x")] wf_on_induct 1 THEN assume_tac 1);
 | 
|  |    168 | by (rtac ballI 1);
 | 
|  |    169 | by (eres_inst_tac [("a","b")] wf_on_induct 1 THEN assume_tac 1);
 | 
|  |    170 | by (etac (bspec RS mp) 1);
 | 
|  |    171 | by (fast_tac ZF_cs 1);
 | 
|  |    172 | by (best_tac (ZF_cs addSEs [rmultE]) 1);
 | 
|  |    173 | val wf_on_rmult = result();
 | 
|  |    174 | 
 | 
|  |    175 | 
 | 
|  |    176 | goal OrderArith.thy
 | 
|  |    177 |     "!!r s. [| wf(r);  wf(s) |] ==> wf(rmult(field(r),r,field(s),s))";
 | 
|  |    178 | by (asm_full_simp_tac (ZF_ss addsimps [wf_iff_wf_on_field]) 1);
 | 
|  |    179 | by (rtac (field_rmult RSN (2, wf_on_subset_A)) 1);
 | 
|  |    180 | by (REPEAT (ares_tac [wf_on_rmult] 1));
 | 
|  |    181 | val wf_rmult = result();
 | 
|  |    182 | 
 | 
|  |    183 | goal OrderArith.thy 
 | 
|  |    184 |     "!!r s. [| well_ord(A,r);  well_ord(B,s) |] ==> \
 | 
|  |    185 | \           well_ord(A*B, rmult(A,r,B,s))";
 | 
|  |    186 | by (rtac well_ordI 1);
 | 
|  |    187 | by (asm_full_simp_tac (ZF_ss addsimps [well_ord_def, wf_on_rmult]) 1);
 | 
|  |    188 | by (asm_full_simp_tac 
 | 
|  |    189 |     (ZF_ss addsimps [well_ord_def, tot_ord_def, linear_rmult]) 1);
 | 
|  |    190 | val well_ord_rmult = result();
 | 
|  |    191 | 
 | 
|  |    192 | 
 | 
|  |    193 | (**** Inverse image of a relation ****)
 | 
|  |    194 | 
 | 
|  |    195 | (** Rewrite rule **)
 | 
|  |    196 | 
 | 
|  |    197 | goalw OrderArith.thy [rvimage_def] 
 | 
|  |    198 |     "<a,b> : rvimage(A,f,r)  <->  <f`a,f`b>: r & a:A & b:A";
 | 
|  |    199 | by (fast_tac ZF_cs 1);
 | 
|  |    200 | val rvimage_iff = result();
 | 
|  |    201 | 
 | 
|  |    202 | (** Type checking **)
 | 
|  |    203 | 
 | 
|  |    204 | goalw OrderArith.thy [rvimage_def] "rvimage(A,f,r) <= A*A";
 | 
|  |    205 | by (rtac Collect_subset 1);
 | 
|  |    206 | val rvimage_type = result();
 | 
|  |    207 | 
 | 
|  |    208 | val field_rvimage = standard (rvimage_type RS field_rel_subset);
 | 
|  |    209 | 
 | 
|  |    210 | 
 | 
|  |    211 | (** Linearity **)
 | 
|  |    212 | 
 | 
|  |    213 | val [finj,lin] = goalw OrderArith.thy [inj_def]
 | 
|  |    214 |     "[| f: inj(A,B);  linear(B,r) |] ==> linear(A,rvimage(A,f,r))";
 | 
|  |    215 | by (rewtac linear_def);    (*Note! the premises are NOT rewritten*)
 | 
|  |    216 | by (REPEAT_FIRST (ares_tac [ballI]));
 | 
|  |    217 | by (asm_simp_tac (ZF_ss addsimps [rvimage_iff]) 1);
 | 
|  |    218 | by (cut_facts_tac [finj] 1);
 | 
|  |    219 | by (res_inst_tac [("x","f`x"), ("y","f`y")] (lin RS linearE) 1);
 | 
|  |    220 | by (REPEAT_SOME (fast_tac (ZF_cs addSIs [apply_type])));
 | 
|  |    221 | val linear_rvimage = result();
 | 
|  |    222 | 
 | 
|  |    223 | 
 | 
|  |    224 | (** Well-foundedness **)
 | 
|  |    225 | 
 | 
|  |    226 | goal OrderArith.thy
 | 
|  |    227 |     "!!r. [| f: A->B;  wf[B](r) |] ==> wf[A](rvimage(A,f,r))";
 | 
|  |    228 | by (rtac wf_onI2 1);
 | 
|  |    229 | by (subgoal_tac "ALL z:A. f`z=f`y --> z: Ba" 1);
 | 
|  |    230 | by (fast_tac ZF_cs 1);
 | 
|  |    231 | by (eres_inst_tac [("a","f`y")] wf_on_induct 1);
 | 
|  |    232 | by (fast_tac (ZF_cs addSIs [apply_type]) 1);
 | 
|  |    233 | by (best_tac (ZF_cs addSIs [apply_type] addSDs [rvimage_iff RS iffD1]) 1);
 | 
|  |    234 | val wf_on_rvimage = result();
 | 
|  |    235 | 
 | 
|  |    236 | goal OrderArith.thy 
 | 
|  |    237 |     "!!r. [| f: inj(A,B);  well_ord(B,r) |] ==> well_ord(A, rvimage(A,f,r))";
 | 
|  |    238 | by (rtac well_ordI 1);
 | 
|  |    239 | by (rewrite_goals_tac [well_ord_def, tot_ord_def]);
 | 
|  |    240 | by (fast_tac (ZF_cs addSIs [wf_on_rvimage, inj_is_fun]) 1);
 | 
|  |    241 | by (fast_tac (ZF_cs addSIs [linear_rvimage]) 1);
 | 
|  |    242 | val well_ord_rvimage = result();
 |