| author | wenzelm | 
| Mon, 18 Sep 2000 14:49:51 +0200 | |
| changeset 10017 | e146bbfc38c1 | 
| parent 9747 | 043098ba5098 | 
| child 10186 | 499637e8f2c6 | 
| permissions | -rw-r--r-- | 
| 9422 | 1 | (* Title : HOL/Real/PNat.ML | 
| 7219 | 2 | ID : $Id$ | 
| 5078 | 3 | Author : Jacques D. Fleuriot | 
| 4 | Copyright : 1998 University of Cambridge | |
| 9422 | 5 | |
| 6 | The positive naturals -- proofs mainly as in theory Nat. | |
| 5078 | 7 | *) | 
| 8 | ||
| 9 | Goal "mono(%X. {1} Un (Suc``X))";
 | |
| 10 | by (REPEAT (ares_tac [monoI, subset_refl, image_mono, Un_mono] 1)); | |
| 11 | qed "pnat_fun_mono"; | |
| 12 | ||
| 9108 | 13 | bind_thm ("pnat_unfold", pnat_fun_mono RS (pnat_def RS def_lfp_Tarski));
 | 
| 5078 | 14 | |
| 15 | Goal "1 : pnat"; | |
| 16 | by (stac pnat_unfold 1); | |
| 17 | by (rtac (singletonI RS UnI1) 1); | |
| 18 | qed "one_RepI"; | |
| 19 | ||
| 20 | Addsimps [one_RepI]; | |
| 21 | ||
| 22 | Goal "i: pnat ==> Suc(i) : pnat"; | |
| 23 | by (stac pnat_unfold 1); | |
| 24 | by (etac (imageI RS UnI2) 1); | |
| 25 | qed "pnat_Suc_RepI"; | |
| 26 | ||
| 27 | Goal "2 : pnat"; | |
| 28 | by (rtac (one_RepI RS pnat_Suc_RepI) 1); | |
| 29 | qed "two_RepI"; | |
| 30 | ||
| 31 | (*** Induction ***) | |
| 32 | ||
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 33 | val major::prems = Goal | 
| 5078 | 34 | "[| i: pnat; P(1); \ | 
| 35 | \ !!j. [| j: pnat; P(j) |] ==> P(Suc(j)) |] ==> P(i)"; | |
| 36 | by (rtac ([pnat_def, pnat_fun_mono, major] MRS def_induct) 1); | |
| 37 | by (blast_tac (claset() addIs prems) 1); | |
| 38 | qed "PNat_induct"; | |
| 39 | ||
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 40 | val prems = Goalw [pnat_one_def,pnat_Suc_def] | 
| 5078 | 41 | "[| P(1p); \ | 
| 42 | \ !!n. P(n) ==> P(pSuc n) |] ==> P(n)"; | |
| 43 | by (rtac (Rep_pnat_inverse RS subst) 1); | |
| 44 | by (rtac (Rep_pnat RS PNat_induct) 1); | |
| 45 | by (REPEAT (ares_tac prems 1 | |
| 46 | ORELSE eresolve_tac [Abs_pnat_inverse RS subst] 1)); | |
| 47 | qed "pnat_induct"; | |
| 48 | ||
| 49 | (*Perform induction on n. *) | |
| 5184 | 50 | fun pnat_ind_tac a i = | 
| 9747 | 51 | induct_thm_tac pnat_induct a i THEN rename_last_tac a [""] (i+1); | 
| 5078 | 52 | |
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 53 | val prems = Goal | 
| 5078 | 54 | "[| !!x. P x 1p; \ | 
| 55 | \ !!y. P 1p (pSuc y); \ | |
| 56 | \ !!x y. [| P x y |] ==> P (pSuc x) (pSuc y) \ | |
| 57 | \ |] ==> P m n"; | |
| 58 | by (res_inst_tac [("x","m")] spec 1);
 | |
| 59 | by (pnat_ind_tac "n" 1); | |
| 60 | by (rtac allI 2); | |
| 61 | by (pnat_ind_tac "x" 2); | |
| 62 | by (REPEAT (ares_tac (prems@[allI]) 1 ORELSE etac spec 1)); | |
| 63 | qed "pnat_diff_induct"; | |
| 64 | ||
| 65 | (*Case analysis on the natural numbers*) | |
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 66 | val prems = Goal | 
| 5078 | 67 | "[| n=1p ==> P; !!x. n = pSuc(x) ==> P |] ==> P"; | 
| 68 | by (subgoal_tac "n=1p | (EX x. n = pSuc(x))" 1); | |
| 69 | by (fast_tac (claset() addSEs prems) 1); | |
| 70 | by (pnat_ind_tac "n" 1); | |
| 71 | by (rtac (refl RS disjI1) 1); | |
| 72 | by (Blast_tac 1); | |
| 73 | qed "pnatE"; | |
| 74 | ||
| 75 | (*** Isomorphisms: Abs_Nat and Rep_Nat ***) | |
| 76 | ||
| 77 | Goal "inj_on Abs_pnat pnat"; | |
| 78 | by (rtac inj_on_inverseI 1); | |
| 79 | by (etac Abs_pnat_inverse 1); | |
| 80 | qed "inj_on_Abs_pnat"; | |
| 81 | ||
| 82 | Addsimps [inj_on_Abs_pnat RS inj_on_iff]; | |
| 83 | ||
| 84 | Goal "inj(Rep_pnat)"; | |
| 85 | by (rtac inj_inverseI 1); | |
| 86 | by (rtac Rep_pnat_inverse 1); | |
| 87 | qed "inj_Rep_pnat"; | |
| 88 | ||
| 89 | Goal "0 ~: pnat"; | |
| 90 | by (stac pnat_unfold 1); | |
| 91 | by Auto_tac; | |
| 92 | qed "zero_not_mem_pnat"; | |
| 93 | ||
| 94 | (* 0 : pnat ==> P *) | |
| 95 | bind_thm ("zero_not_mem_pnatE", zero_not_mem_pnat RS notE);
 | |
| 96 | ||
| 97 | Addsimps [zero_not_mem_pnat]; | |
| 98 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 99 | Goal "x : pnat ==> 0 < x"; | 
| 5078 | 100 | by (dtac (pnat_unfold RS subst) 1); | 
| 101 | by Auto_tac; | |
| 102 | qed "mem_pnat_gt_zero"; | |
| 103 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 104 | Goal "0 < x ==> x: pnat"; | 
| 5078 | 105 | by (stac pnat_unfold 1); | 
| 106 | by (dtac (gr_implies_not0 RS not0_implies_Suc) 1); | |
| 107 | by (etac exE 1 THEN Asm_simp_tac 1); | |
| 108 | by (induct_tac "m" 1); | |
| 109 | by (auto_tac (claset(),simpset() | |
| 110 | addsimps [one_RepI]) THEN dtac pnat_Suc_RepI 1); | |
| 111 | by (Blast_tac 1); | |
| 112 | qed "gt_0_mem_pnat"; | |
| 113 | ||
| 114 | Goal "(x: pnat) = (0 < x)"; | |
| 115 | by (blast_tac (claset() addDs [mem_pnat_gt_zero,gt_0_mem_pnat]) 1); | |
| 116 | qed "mem_pnat_gt_0_iff"; | |
| 117 | ||
| 118 | Goal "0 < Rep_pnat x"; | |
| 119 | by (rtac (Rep_pnat RS mem_pnat_gt_zero) 1); | |
| 120 | qed "Rep_pnat_gt_zero"; | |
| 121 | ||
| 122 | Goalw [pnat_add_def] "(x::pnat) + y = y + x"; | |
| 123 | by (simp_tac (simpset() addsimps [add_commute]) 1); | |
| 124 | qed "pnat_add_commute"; | |
| 125 | ||
| 126 | (** alternative definition for pnat **) | |
| 127 | (** order isomorphism **) | |
| 128 | Goal "pnat = {x::nat. 0 < x}";
 | |
| 129 | by (rtac set_ext 1); | |
| 130 | by (simp_tac (simpset() addsimps | |
| 131 | [mem_pnat_gt_0_iff]) 1); | |
| 132 | qed "Collect_pnat_gt_0"; | |
| 133 | ||
| 134 | (*** Distinctness of constructors ***) | |
| 135 | ||
| 136 | Goalw [pnat_one_def,pnat_Suc_def] "pSuc(m) ~= 1p"; | |
| 137 | by (rtac (inj_on_Abs_pnat RS inj_on_contraD) 1); | |
| 138 | by (rtac (Rep_pnat_gt_zero RS Suc_mono RS less_not_refl2) 1); | |
| 139 | by (REPEAT (resolve_tac [Rep_pnat RS pnat_Suc_RepI, one_RepI] 1)); | |
| 140 | qed "pSuc_not_one"; | |
| 141 | ||
| 142 | bind_thm ("one_not_pSuc", pSuc_not_one RS not_sym);
 | |
| 143 | ||
| 144 | AddIffs [pSuc_not_one,one_not_pSuc]; | |
| 145 | ||
| 146 | bind_thm ("pSuc_neq_one", (pSuc_not_one RS notE));
 | |
| 9108 | 147 | bind_thm ("one_neq_pSuc", pSuc_neq_one RS pSuc_neq_one);
 | 
| 5078 | 148 | |
| 149 | (** Injectiveness of pSuc **) | |
| 150 | ||
| 151 | Goalw [pnat_Suc_def] "inj(pSuc)"; | |
| 152 | by (rtac injI 1); | |
| 153 | by (dtac (inj_on_Abs_pnat RS inj_onD) 1); | |
| 154 | by (REPEAT (resolve_tac [Rep_pnat, pnat_Suc_RepI] 1)); | |
| 155 | by (dtac (inj_Suc RS injD) 1); | |
| 156 | by (etac (inj_Rep_pnat RS injD) 1); | |
| 157 | qed "inj_pSuc"; | |
| 158 | ||
| 9108 | 159 | bind_thm ("pSuc_inject", inj_pSuc RS injD);
 | 
| 5078 | 160 | |
| 161 | Goal "(pSuc(m)=pSuc(n)) = (m=n)"; | |
| 162 | by (EVERY1 [rtac iffI, etac pSuc_inject, etac arg_cong]); | |
| 163 | qed "pSuc_pSuc_eq"; | |
| 164 | ||
| 165 | AddIffs [pSuc_pSuc_eq]; | |
| 166 | ||
| 167 | Goal "n ~= pSuc(n)"; | |
| 168 | by (pnat_ind_tac "n" 1); | |
| 169 | by (ALLGOALS Asm_simp_tac); | |
| 170 | qed "n_not_pSuc_n"; | |
| 171 | ||
| 172 | bind_thm ("pSuc_n_not_n", n_not_pSuc_n RS not_sym);
 | |
| 173 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 174 | Goal "n ~= 1p ==> EX m. n = pSuc m"; | 
| 5078 | 175 | by (rtac pnatE 1); | 
| 176 | by (REPEAT (Blast_tac 1)); | |
| 177 | qed "not1p_implies_pSuc"; | |
| 178 | ||
| 179 | Goal "pSuc m = m + 1p"; | |
| 180 | by (auto_tac (claset(),simpset() addsimps [pnat_Suc_def, | |
| 181 | pnat_one_def,Abs_pnat_inverse,pnat_add_def])); | |
| 182 | qed "pSuc_is_plus_one"; | |
| 183 | ||
| 184 | Goal | |
| 185 | "(Rep_pnat x + Rep_pnat y): pnat"; | |
| 186 | by (cut_facts_tac [[Rep_pnat_gt_zero, | |
| 187 | Rep_pnat_gt_zero] MRS add_less_mono,Collect_pnat_gt_0] 1); | |
| 188 | by (etac ssubst 1); | |
| 189 | by Auto_tac; | |
| 190 | qed "sum_Rep_pnat"; | |
| 191 | ||
| 192 | Goalw [pnat_add_def] | |
| 193 | "Rep_pnat x + Rep_pnat y = Rep_pnat (x + y)"; | |
| 194 | by (simp_tac (simpset() addsimps [sum_Rep_pnat RS | |
| 195 | Abs_pnat_inverse]) 1); | |
| 196 | qed "sum_Rep_pnat_sum"; | |
| 197 | ||
| 198 | Goalw [pnat_add_def] | |
| 199 | "(x + y) + z = x + (y + (z::pnat))"; | |
| 200 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | |
| 201 | by (simp_tac (simpset() addsimps [sum_Rep_pnat RS | |
| 202 | Abs_pnat_inverse,add_assoc]) 1); | |
| 203 | qed "pnat_add_assoc"; | |
| 204 | ||
| 205 | Goalw [pnat_add_def] "x + (y + z) = y + (x + (z::pnat))"; | |
| 206 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | |
| 207 | by (simp_tac (simpset() addsimps [sum_Rep_pnat RS | |
| 208 | Abs_pnat_inverse,add_left_commute]) 1); | |
| 209 | qed "pnat_add_left_commute"; | |
| 210 | ||
| 211 | (*Addition is an AC-operator*) | |
| 9108 | 212 | bind_thms ("pnat_add_ac", [pnat_add_assoc, pnat_add_commute, pnat_add_left_commute]);
 | 
| 5078 | 213 | |
| 214 | Goalw [pnat_add_def] "((x::pnat) + y = x + z) = (y = z)"; | |
| 8866 | 215 | by (auto_tac (claset() addDs [inj_on_Abs_pnat RS inj_onD, | 
| 5078 | 216 | inj_Rep_pnat RS injD],simpset() addsimps [sum_Rep_pnat])); | 
| 217 | qed "pnat_add_left_cancel"; | |
| 218 | ||
| 219 | Goalw [pnat_add_def] "(y + (x::pnat) = z + x) = (y = z)"; | |
| 8866 | 220 | by (auto_tac (claset() addDs [inj_on_Abs_pnat RS inj_onD, | 
| 5078 | 221 | inj_Rep_pnat RS injD],simpset() addsimps [sum_Rep_pnat])); | 
| 222 | qed "pnat_add_right_cancel"; | |
| 223 | ||
| 224 | Goalw [pnat_add_def] "!(y::pnat). x + y ~= x"; | |
| 225 | by (rtac (Rep_pnat_inverse RS subst) 1); | |
| 8866 | 226 | by (auto_tac (claset() addDs [inj_on_Abs_pnat RS inj_onD] | 
| 5078 | 227 | addSDs [add_eq_self_zero], | 
| 228 | simpset() addsimps [sum_Rep_pnat, Rep_pnat,Abs_pnat_inverse, | |
| 8866 | 229 | Rep_pnat_gt_zero RS less_not_refl2])); | 
| 5078 | 230 | qed "pnat_no_add_ident"; | 
| 231 | ||
| 232 | ||
| 233 | (***) (***) (***) (***) (***) (***) (***) (***) (***) | |
| 234 | ||
| 235 | (*** pnat_less ***) | |
| 236 | ||
| 237 | Goalw [pnat_less_def] | |
| 5148 
74919e8f221c
More tidying and removal of "\!\!... from Goal commands
 paulson parents: 
5143diff
changeset | 238 | "[| x < (y::pnat); y < z |] ==> x < z"; | 
| 5078 | 239 | by ((etac less_trans 1) THEN assume_tac 1); | 
| 240 | qed "pnat_less_trans"; | |
| 241 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 242 | Goalw [pnat_less_def] "x < (y::pnat) ==> ~ y < x"; | 
| 5078 | 243 | by (etac less_not_sym 1); | 
| 244 | qed "pnat_less_not_sym"; | |
| 245 | ||
| 5459 | 246 | (* [| x < y; ~P ==> y < x |] ==> P *) | 
| 247 | bind_thm ("pnat_less_asym", pnat_less_not_sym RS swap);
 | |
| 5078 | 248 | |
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 249 | Goalw [pnat_less_def] "~ y < (y::pnat)"; | 
| 5078 | 250 | by Auto_tac; | 
| 251 | qed "pnat_less_not_refl"; | |
| 252 | ||
| 253 | bind_thm ("pnat_less_irrefl",pnat_less_not_refl RS notE);
 | |
| 254 | ||
| 255 | Goalw [pnat_less_def] | |
| 5148 
74919e8f221c
More tidying and removal of "\!\!... from Goal commands
 paulson parents: 
5143diff
changeset | 256 | "x < (y::pnat) ==> x ~= y"; | 
| 5078 | 257 | by Auto_tac; | 
| 258 | qed "pnat_less_not_refl2"; | |
| 259 | ||
| 260 | Goal "~ Rep_pnat y < 0"; | |
| 261 | by Auto_tac; | |
| 262 | qed "Rep_pnat_not_less0"; | |
| 263 | ||
| 264 | (*** Rep_pnat < 0 ==> P ***) | |
| 265 | bind_thm ("Rep_pnat_less_zeroE",Rep_pnat_not_less0 RS notE);
 | |
| 266 | ||
| 267 | Goal "~ Rep_pnat y < 1"; | |
| 268 | by (auto_tac (claset(),simpset() addsimps [less_Suc_eq, | |
| 269 | Rep_pnat_gt_zero,less_not_refl2])); | |
| 270 | qed "Rep_pnat_not_less_one"; | |
| 271 | ||
| 272 | (*** Rep_pnat < 1 ==> P ***) | |
| 273 | bind_thm ("Rep_pnat_less_oneE",Rep_pnat_not_less_one RS notE);
 | |
| 274 | ||
| 275 | Goalw [pnat_less_def] | |
| 5148 
74919e8f221c
More tidying and removal of "\!\!... from Goal commands
 paulson parents: 
5143diff
changeset | 276 | "x < (y::pnat) ==> Rep_pnat y ~= 1"; | 
| 5078 | 277 | by (auto_tac (claset(),simpset() | 
| 278 | addsimps [Rep_pnat_not_less_one] delsimps [less_one])); | |
| 279 | qed "Rep_pnat_gt_implies_not0"; | |
| 280 | ||
| 281 | Goalw [pnat_less_def] | |
| 282 | "(x::pnat) < y | x = y | y < x"; | |
| 283 | by (cut_facts_tac [less_linear] 1); | |
| 284 | by (fast_tac (claset() addIs [inj_Rep_pnat RS injD]) 1); | |
| 285 | qed "pnat_less_linear"; | |
| 286 | ||
| 287 | Goalw [le_def] "1 <= Rep_pnat x"; | |
| 288 | by (rtac Rep_pnat_not_less_one 1); | |
| 289 | qed "Rep_pnat_le_one"; | |
| 290 | ||
| 291 | Goalw [pnat_less_def] | |
| 9043 
ca761fe227d8
First round of changes, towards installation of simprocs
 paulson parents: 
8866diff
changeset | 292 | "!! (z1::nat). z1 < z2 ==> EX z3. z1 + Rep_pnat z3 = z2"; | 
| 5078 | 293 | by (dtac less_imp_add_positive 1); | 
| 5758 
27a2b36efd95
corrected auto_tac (applications of unsafe wrappers)
 oheimb parents: 
5588diff
changeset | 294 | by (force_tac (claset() addSIs [Abs_pnat_inverse], | 
| 
27a2b36efd95
corrected auto_tac (applications of unsafe wrappers)
 oheimb parents: 
5588diff
changeset | 295 | simpset() addsimps [Collect_pnat_gt_0]) 1); | 
| 5078 | 296 | qed "lemma_less_ex_sum_Rep_pnat"; | 
| 297 | ||
| 298 | ||
| 299 | (*** pnat_le ***) | |
| 300 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 301 | Goalw [pnat_le_def] "~ (x::pnat) < y ==> y <= x"; | 
| 5078 | 302 | by (assume_tac 1); | 
| 303 | qed "pnat_leI"; | |
| 304 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 305 | Goalw [pnat_le_def] "(x::pnat) <= y ==> ~ y < x"; | 
| 5078 | 306 | by (assume_tac 1); | 
| 307 | qed "pnat_leD"; | |
| 308 | ||
| 9108 | 309 | bind_thm ("pnat_leE", make_elim pnat_leD);
 | 
| 5078 | 310 | |
| 311 | Goal "(~ (x::pnat) < y) = (y <= x)"; | |
| 312 | by (blast_tac (claset() addIs [pnat_leI] addEs [pnat_leE]) 1); | |
| 313 | qed "pnat_not_less_iff_le"; | |
| 314 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 315 | Goalw [pnat_le_def] "~(x::pnat) <= y ==> y < x"; | 
| 5078 | 316 | by (Blast_tac 1); | 
| 317 | qed "pnat_not_leE"; | |
| 318 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 319 | Goalw [pnat_le_def] "(x::pnat) < y ==> x <= y"; | 
| 5078 | 320 | by (blast_tac (claset() addEs [pnat_less_asym]) 1); | 
| 321 | qed "pnat_less_imp_le"; | |
| 322 | ||
| 323 | (** Equivalence of m<=n and m<n | m=n **) | |
| 324 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 325 | Goalw [pnat_le_def] "m <= n ==> m < n | m=(n::pnat)"; | 
| 5078 | 326 | by (cut_facts_tac [pnat_less_linear] 1); | 
| 327 | by (blast_tac (claset() addEs [pnat_less_irrefl,pnat_less_asym]) 1); | |
| 328 | qed "pnat_le_imp_less_or_eq"; | |
| 329 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 330 | Goalw [pnat_le_def] "m<n | m=n ==> m <=(n::pnat)"; | 
| 5078 | 331 | by (cut_facts_tac [pnat_less_linear] 1); | 
| 332 | by (blast_tac (claset() addSEs [pnat_less_irrefl] addEs [pnat_less_asym]) 1); | |
| 333 | qed "pnat_less_or_eq_imp_le"; | |
| 334 | ||
| 335 | Goal "(m <= (n::pnat)) = (m < n | m=n)"; | |
| 336 | by (REPEAT(ares_tac [iffI,pnat_less_or_eq_imp_le,pnat_le_imp_less_or_eq] 1)); | |
| 337 | qed "pnat_le_eq_less_or_eq"; | |
| 338 | ||
| 339 | Goal "n <= (n::pnat)"; | |
| 340 | by (simp_tac (simpset() addsimps [pnat_le_eq_less_or_eq]) 1); | |
| 341 | qed "pnat_le_refl"; | |
| 342 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 343 | Goal "[| i < j; j <= k |] ==> i < (k::pnat)"; | 
| 5078 | 344 | by (dtac pnat_le_imp_less_or_eq 1); | 
| 345 | by (blast_tac (claset() addIs [pnat_less_trans]) 1); | |
| 346 | qed "pnat_less_le_trans"; | |
| 347 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 348 | Goal "[| i <= j; j <= k |] ==> i <= (k::pnat)"; | 
| 5078 | 349 | by (EVERY1[dtac pnat_le_imp_less_or_eq, | 
| 350 | dtac pnat_le_imp_less_or_eq, | |
| 351 | rtac pnat_less_or_eq_imp_le, | |
| 352 | blast_tac (claset() addIs [pnat_less_trans])]); | |
| 353 | qed "pnat_le_trans"; | |
| 354 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 355 | Goal "[| m <= n; n <= m |] ==> m = (n::pnat)"; | 
| 5078 | 356 | by (EVERY1[dtac pnat_le_imp_less_or_eq, | 
| 357 | dtac pnat_le_imp_less_or_eq, | |
| 358 | blast_tac (claset() addIs [pnat_less_asym])]); | |
| 359 | qed "pnat_le_anti_sym"; | |
| 360 | ||
| 361 | Goal "(m::pnat) < n = (m <= n & m ~= n)"; | |
| 362 | by (rtac iffI 1); | |
| 363 | by (rtac conjI 1); | |
| 364 | by (etac pnat_less_imp_le 1); | |
| 365 | by (etac pnat_less_not_refl2 1); | |
| 366 | by (blast_tac (claset() addSDs [pnat_le_imp_less_or_eq]) 1); | |
| 367 | qed "pnat_less_le"; | |
| 368 | ||
| 369 | ||
| 370 | (***) (***) (***) (***) (***) (***) (***) (***) | |
| 371 | ||
| 372 | (*** alternative definition for pnat_le ***) | |
| 373 | Goalw [pnat_le_def,pnat_less_def] | |
| 374 | "((m::pnat) <= n) = (Rep_pnat m <= Rep_pnat n)"; | |
| 375 | by (auto_tac (claset() addSIs [leI] addSEs [leD],simpset())); | |
| 376 | qed "pnat_le_iff_Rep_pnat_le"; | |
| 377 | ||
| 378 | Goal "!!k::pnat. (k + m <= k + n) = (m<=n)"; | |
| 379 | by (simp_tac (simpset() addsimps [pnat_le_iff_Rep_pnat_le, | |
| 380 | sum_Rep_pnat_sum RS sym]) 1); | |
| 381 | qed "pnat_add_left_cancel_le"; | |
| 382 | ||
| 383 | Goalw [pnat_less_def] "!!k::pnat. (k + m < k + n) = (m<n)"; | |
| 384 | by (simp_tac (simpset() addsimps [sum_Rep_pnat_sum RS sym]) 1); | |
| 385 | qed "pnat_add_left_cancel_less"; | |
| 386 | ||
| 387 | Addsimps [pnat_add_left_cancel, pnat_add_right_cancel, | |
| 388 | pnat_add_left_cancel_le, pnat_add_left_cancel_less]; | |
| 389 | ||
| 5143 
b94cd208f073
Removal of leading "\!\!..." from most Goal commands
 paulson parents: 
5078diff
changeset | 390 | Goalw [pnat_less_def] "i+j < (k::pnat) ==> i<k"; | 
| 5078 | 391 | by (auto_tac (claset() addEs [add_lessD1], | 
| 392 | simpset() addsimps [sum_Rep_pnat_sum RS sym])); | |
| 393 | qed "pnat_add_lessD1"; | |
| 394 | ||
| 395 | Goal "!!i::pnat. ~ (i+j < i)"; | |
| 396 | by (rtac notI 1); | |
| 397 | by (etac (pnat_add_lessD1 RS pnat_less_irrefl) 1); | |
| 398 | qed "pnat_not_add_less1"; | |
| 399 | ||
| 400 | Goal "!!i::pnat. ~ (j+i < i)"; | |
| 401 | by (simp_tac (simpset() addsimps [pnat_add_commute, pnat_not_add_less1]) 1); | |
| 402 | qed "pnat_not_add_less2"; | |
| 403 | ||
| 404 | AddIffs [pnat_not_add_less1, pnat_not_add_less2]; | |
| 405 | ||
| 406 | Goal "m + k <= n --> m <= (n::pnat)"; | |
| 407 | by (simp_tac (simpset() addsimps [pnat_le_iff_Rep_pnat_le, | |
| 408 | sum_Rep_pnat_sum RS sym]) 1); | |
| 409 | qed_spec_mp "pnat_add_leD1"; | |
| 410 | ||
| 411 | Goal "!!n::pnat. m + k <= n ==> k <= n"; | |
| 412 | by (full_simp_tac (simpset() addsimps [pnat_add_commute]) 1); | |
| 413 | by (etac pnat_add_leD1 1); | |
| 414 | qed_spec_mp "pnat_add_leD2"; | |
| 415 | ||
| 416 | Goal "!!n::pnat. m + k <= n ==> m <= n & k <= n"; | |
| 417 | by (blast_tac (claset() addDs [pnat_add_leD1, pnat_add_leD2]) 1); | |
| 418 | bind_thm ("pnat_add_leE", result() RS conjE);
 | |
| 419 | ||
| 420 | Goalw [pnat_less_def] | |
| 421 | "!!k l::pnat. [| k < l; m + l = k + n |] ==> m < n"; | |
| 422 | by (rtac less_add_eq_less 1 THEN assume_tac 1); | |
| 423 | by (auto_tac (claset(),simpset() addsimps [sum_Rep_pnat_sum])); | |
| 424 | qed "pnat_less_add_eq_less"; | |
| 425 | ||
| 426 | (* ordering on positive naturals in terms of existence of sum *) | |
| 427 | (* could provide alternative definition -- Gleason *) | |
| 428 | Goalw [pnat_less_def,pnat_add_def] | |
| 9043 
ca761fe227d8
First round of changes, towards installation of simprocs
 paulson parents: 
8866diff
changeset | 429 | "(z1::pnat) < z2 = (EX z3. z1 + z3 = z2)"; | 
| 5078 | 430 | by (rtac iffI 1); | 
| 431 | by (res_inst_tac [("t","z2")] (Rep_pnat_inverse RS subst) 1);
 | |
| 432 | by (dtac lemma_less_ex_sum_Rep_pnat 1); | |
| 433 | by (etac exE 1 THEN res_inst_tac [("x","z3")] exI 1);
 | |
| 434 | by (auto_tac (claset(),simpset() addsimps [sum_Rep_pnat_sum,Rep_pnat_inverse])); | |
| 435 | by (res_inst_tac [("t","Rep_pnat z1")] (add_0_right RS subst) 1);
 | |
| 436 | by (auto_tac (claset(),simpset() addsimps [sum_Rep_pnat_sum RS sym, | |
| 437 | Rep_pnat_gt_zero] delsimps [add_0_right])); | |
| 438 | qed "pnat_less_iff"; | |
| 439 | ||
| 9043 
ca761fe227d8
First round of changes, towards installation of simprocs
 paulson parents: 
8866diff
changeset | 440 | Goal "(EX (x::pnat). z1 + x = z2) | z1 = z2 \ | 
| 
ca761fe227d8
First round of changes, towards installation of simprocs
 paulson parents: 
8866diff
changeset | 441 | \ |(EX x. z2 + x = z1)"; | 
| 5078 | 442 | by (cut_facts_tac [pnat_less_linear] 1); | 
| 443 | by (asm_full_simp_tac (simpset() addsimps [pnat_less_iff]) 1); | |
| 444 | qed "pnat_linear_Ex_eq"; | |
| 445 | ||
| 446 | Goal "!!(x::pnat). x + y = z ==> x < z"; | |
| 447 | by (rtac (pnat_less_iff RS iffD2) 1); | |
| 448 | by (Blast_tac 1); | |
| 449 | qed "pnat_eq_lessI"; | |
| 450 | ||
| 451 | (*** Monotonicity of Addition ***) | |
| 452 | ||
| 453 | (*strict, in 1st argument*) | |
| 454 | Goalw [pnat_less_def] "!!i j k::pnat. i < j ==> i + k < j + k"; | |
| 455 | by (auto_tac (claset() addIs [add_less_mono1], | |
| 456 | simpset() addsimps [sum_Rep_pnat_sum RS sym])); | |
| 457 | qed "pnat_add_less_mono1"; | |
| 458 | ||
| 459 | Goalw [pnat_less_def] "!!i j k::pnat. [|i < j; k < l|] ==> i + k < j + l"; | |
| 460 | by (auto_tac (claset() addIs [add_less_mono], | |
| 461 | simpset() addsimps [sum_Rep_pnat_sum RS sym])); | |
| 462 | qed "pnat_add_less_mono"; | |
| 463 | ||
| 464 | Goalw [pnat_less_def] | |
| 5148 
74919e8f221c
More tidying and removal of "\!\!... from Goal commands
 paulson parents: 
5143diff
changeset | 465 | "!!f. [| !!i j::pnat. i<j ==> f(i) < f(j); \ | 
| 5078 | 466 | \ i <= j \ | 
| 467 | \ |] ==> f(i) <= (f(j)::pnat)"; | |
| 468 | by (auto_tac (claset() addSDs [inj_Rep_pnat RS injD], | |
| 469 | simpset() addsimps [pnat_le_iff_Rep_pnat_le, | |
| 5588 | 470 | order_le_less])); | 
| 5078 | 471 | qed "pnat_less_mono_imp_le_mono"; | 
| 472 | ||
| 473 | Goal "!!i j k::pnat. i<=j ==> i + k <= j + k"; | |
| 474 | by (res_inst_tac [("f", "%j. j+k")] pnat_less_mono_imp_le_mono 1);
 | |
| 475 | by (etac pnat_add_less_mono1 1); | |
| 476 | by (assume_tac 1); | |
| 477 | qed "pnat_add_le_mono1"; | |
| 478 | ||
| 479 | Goal "!!k l::pnat. [|i<=j; k<=l |] ==> i + k <= j + l"; | |
| 480 | by (etac (pnat_add_le_mono1 RS pnat_le_trans) 1); | |
| 481 | by (simp_tac (simpset() addsimps [pnat_add_commute]) 1); | |
| 482 | (*j moves to the end because it is free while k, l are bound*) | |
| 483 | by (etac pnat_add_le_mono1 1); | |
| 484 | qed "pnad_add_le_mono"; | |
| 485 | ||
| 486 | Goal "1 * Rep_pnat n = Rep_pnat n"; | |
| 487 | by (Asm_simp_tac 1); | |
| 488 | qed "Rep_pnat_mult_1"; | |
| 489 | ||
| 490 | Goal "Rep_pnat n * 1 = Rep_pnat n"; | |
| 491 | by (Asm_simp_tac 1); | |
| 492 | qed "Rep_pnat_mult_1_right"; | |
| 493 | ||
| 494 | Goal | |
| 495 | "(Rep_pnat x * Rep_pnat y): pnat"; | |
| 496 | by (cut_facts_tac [[Rep_pnat_gt_zero, | |
| 497 | Rep_pnat_gt_zero] MRS mult_less_mono1,Collect_pnat_gt_0] 1); | |
| 498 | by (etac ssubst 1); | |
| 499 | by Auto_tac; | |
| 500 | qed "mult_Rep_pnat"; | |
| 501 | ||
| 502 | Goalw [pnat_mult_def] | |
| 503 | "Rep_pnat x * Rep_pnat y = Rep_pnat (x * y)"; | |
| 504 | by (simp_tac (simpset() addsimps [mult_Rep_pnat RS | |
| 505 | Abs_pnat_inverse]) 1); | |
| 506 | qed "mult_Rep_pnat_mult"; | |
| 507 | ||
| 508 | Goalw [pnat_mult_def] "m * n = n * (m::pnat)"; | |
| 509 | by (full_simp_tac (simpset() addsimps [mult_commute]) 1); | |
| 510 | qed "pnat_mult_commute"; | |
| 511 | ||
| 512 | Goalw [pnat_mult_def,pnat_add_def] "(m + n)*k = (m*k) + ((n*k)::pnat)"; | |
| 513 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | |
| 514 | by (simp_tac (simpset() addsimps [mult_Rep_pnat RS | |
| 515 | Abs_pnat_inverse,sum_Rep_pnat RS | |
| 516 | Abs_pnat_inverse, add_mult_distrib]) 1); | |
| 517 | qed "pnat_add_mult_distrib"; | |
| 518 | ||
| 519 | Goalw [pnat_mult_def,pnat_add_def] "k*(m + n) = (k*m) + ((k*n)::pnat)"; | |
| 520 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | |
| 521 | by (simp_tac (simpset() addsimps [mult_Rep_pnat RS | |
| 522 | Abs_pnat_inverse,sum_Rep_pnat RS | |
| 523 | Abs_pnat_inverse, add_mult_distrib2]) 1); | |
| 524 | qed "pnat_add_mult_distrib2"; | |
| 525 | ||
| 526 | Goalw [pnat_mult_def] | |
| 527 | "(x * y) * z = x * (y * (z::pnat))"; | |
| 528 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | |
| 529 | by (simp_tac (simpset() addsimps [mult_Rep_pnat RS | |
| 530 | Abs_pnat_inverse,mult_assoc]) 1); | |
| 531 | qed "pnat_mult_assoc"; | |
| 532 | ||
| 533 | Goalw [pnat_mult_def] "x * (y * z) = y * (x * (z::pnat))"; | |
| 534 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | |
| 535 | by (simp_tac (simpset() addsimps [mult_Rep_pnat RS | |
| 536 | Abs_pnat_inverse,mult_left_commute]) 1); | |
| 537 | qed "pnat_mult_left_commute"; | |
| 538 | ||
| 539 | Goalw [pnat_mult_def] "x * (Abs_pnat 1) = x"; | |
| 540 | by (full_simp_tac (simpset() addsimps [one_RepI RS Abs_pnat_inverse, | |
| 541 | Rep_pnat_inverse]) 1); | |
| 542 | qed "pnat_mult_1"; | |
| 543 | ||
| 544 | Goal "Abs_pnat 1 * x = x"; | |
| 545 | by (full_simp_tac (simpset() addsimps [pnat_mult_1, | |
| 546 | pnat_mult_commute]) 1); | |
| 547 | qed "pnat_mult_1_left"; | |
| 548 | ||
| 549 | (*Multiplication is an AC-operator*) | |
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 550 | bind_thms ("pnat_mult_ac", 
 | 
| 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 551 | [pnat_mult_assoc, pnat_mult_commute, pnat_mult_left_commute]); | 
| 5078 | 552 | |
| 553 | ||
| 554 | Goal "!!i::pnat. i<j ==> k*i < k*j"; | |
| 555 | by (asm_full_simp_tac (simpset() addsimps [pnat_less_def, | |
| 556 | mult_Rep_pnat_mult RS sym,Rep_pnat_gt_zero,mult_less_mono2]) 1); | |
| 557 | qed "pnat_mult_less_mono2"; | |
| 558 | ||
| 559 | Goal "!!i::pnat. i<j ==> i*k < j*k"; | |
| 560 | by (dtac pnat_mult_less_mono2 1); | |
| 561 | by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [pnat_mult_commute]))); | |
| 562 | qed "pnat_mult_less_mono1"; | |
| 563 | ||
| 564 | Goalw [pnat_less_def] "(m*(k::pnat) < n*k) = (m<n)"; | |
| 565 | by (asm_full_simp_tac (simpset() addsimps [mult_Rep_pnat_mult | |
| 566 | RS sym,Rep_pnat_gt_zero]) 1); | |
| 567 | qed "pnat_mult_less_cancel2"; | |
| 568 | ||
| 569 | Goalw [pnat_less_def] "((k::pnat)*m < k*n) = (m<n)"; | |
| 570 | by (asm_full_simp_tac (simpset() addsimps [mult_Rep_pnat_mult | |
| 571 | RS sym,Rep_pnat_gt_zero]) 1); | |
| 572 | qed "pnat_mult_less_cancel1"; | |
| 573 | ||
| 574 | Addsimps [pnat_mult_less_cancel1, pnat_mult_less_cancel2]; | |
| 575 | ||
| 576 | Goalw [pnat_mult_def] "(m*(k::pnat) = n*k) = (m=n)"; | |
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 577 | by (cut_inst_tac [("x","k")] Rep_pnat_gt_zero 1);
 | 
| 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 578 | by (auto_tac (claset() addSDs [inj_on_Abs_pnat RS inj_onD, | 
| 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 579 | inj_Rep_pnat RS injD] | 
| 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 580 | addIs [mult_Rep_pnat], | 
| 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 581 | simpset() addsimps [mult_cancel2])); | 
| 5078 | 582 | qed "pnat_mult_cancel2"; | 
| 583 | ||
| 584 | Goal "((k::pnat)*m = k*n) = (m=n)"; | |
| 585 | by (rtac (pnat_mult_cancel2 RS subst) 1); | |
| 586 | by (auto_tac (claset () addIs [pnat_mult_commute RS subst],simpset())); | |
| 587 | qed "pnat_mult_cancel1"; | |
| 588 | ||
| 589 | Addsimps [pnat_mult_cancel1, pnat_mult_cancel2]; | |
| 590 | ||
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 591 | Goal "!!(z1::pnat). z2*z3 = z4*z5 ==> z2*(z1*z3) = z4*(z1*z5)"; | 
| 5078 | 592 | by (auto_tac (claset() addIs [pnat_mult_cancel1 RS iffD2], | 
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 593 | simpset() addsimps [pnat_mult_left_commute])); | 
| 5078 | 594 | qed "pnat_same_multI2"; | 
| 595 | ||
| 9635 
c9ebf0a1d712
tidied & updated proofs, deleting some unused ones
 paulson parents: 
9422diff
changeset | 596 | val [prem] = Goal | 
| 5078 | 597 | "(!!u. z = Abs_pnat(u) ==> P) ==> P"; | 
| 598 | by (cut_inst_tac [("x1","z")] 
 | |
| 599 | (rewrite_rule [pnat_def] (Rep_pnat RS Abs_pnat_inverse)) 1); | |
| 600 | by (res_inst_tac [("u","Rep_pnat z")] prem 1);
 | |
| 601 | by (dtac (inj_Rep_pnat RS injD) 1); | |
| 602 | by (Asm_simp_tac 1); | |
| 603 | qed "eq_Abs_pnat"; | |
| 604 | ||
| 605 | (** embedding of naturals in positive naturals **) | |
| 606 | ||
| 607 | (* pnat_one_eq! *) | |
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 608 | Goalw [pnat_of_nat_def,pnat_one_def]"1p = pnat_of_nat 0"; | 
| 5078 | 609 | by (Full_simp_tac 1); | 
| 610 | qed "pnat_one_iff"; | |
| 611 | ||
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 612 | Goalw [pnat_of_nat_def,pnat_one_def, | 
| 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 613 | pnat_add_def] "1p + 1p = pnat_of_nat 1"; | 
| 5078 | 614 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | 
| 615 | by (auto_tac (claset() addIs [(gt_0_mem_pnat RS Abs_pnat_inverse RS ssubst)], | |
| 616 | simpset())); | |
| 617 | qed "pnat_two_eq"; | |
| 618 | ||
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 619 | Goal "inj(pnat_of_nat)"; | 
| 5078 | 620 | by (rtac injI 1); | 
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 621 | by (rewtac pnat_of_nat_def); | 
| 5078 | 622 | by (dtac (inj_on_Abs_pnat RS inj_onD) 1); | 
| 623 | by (auto_tac (claset() addSIs [gt_0_mem_pnat],simpset())); | |
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 624 | qed "inj_pnat_of_nat"; | 
| 5078 | 625 | |
| 626 | Goal "0 < n + 1"; | |
| 627 | by Auto_tac; | |
| 628 | qed "nat_add_one_less"; | |
| 629 | ||
| 630 | Goal "0 < n1 + n2 + 1"; | |
| 631 | by Auto_tac; | |
| 632 | qed "nat_add_one_less1"; | |
| 633 | ||
| 634 | (* this worked with one call to auto_tac before! *) | |
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 635 | Goalw [pnat_add_def,pnat_of_nat_def,pnat_one_def] | 
| 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 636 | "pnat_of_nat n1 + pnat_of_nat n2 = \ | 
| 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 637 | \ pnat_of_nat (n1 + n2) + 1p"; | 
| 5078 | 638 | by (res_inst_tac [("f","Abs_pnat")] arg_cong 1);
 | 
| 639 | by (rtac (gt_0_mem_pnat RS Abs_pnat_inverse RS ssubst) 1); | |
| 640 | by (rtac (gt_0_mem_pnat RS Abs_pnat_inverse RS ssubst) 2); | |
| 641 | by (rtac (gt_0_mem_pnat RS Abs_pnat_inverse RS ssubst) 3); | |
| 642 | by (rtac (gt_0_mem_pnat RS Abs_pnat_inverse RS ssubst) 4); | |
| 643 | by (auto_tac (claset(), | |
| 644 | simpset() addsimps [sum_Rep_pnat_sum, | |
| 645 | nat_add_one_less,nat_add_one_less1])); | |
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 646 | qed "pnat_of_nat_add"; | 
| 5078 | 647 | |
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 648 | Goalw [pnat_of_nat_def,pnat_less_def] | 
| 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 649 | "(n < m) = (pnat_of_nat n < pnat_of_nat m)"; | 
| 5078 | 650 | by (auto_tac (claset(),simpset() | 
| 651 | addsimps [Abs_pnat_inverse,Collect_pnat_gt_0])); | |
| 7077 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 652 | qed "pnat_of_nat_less_iff"; | 
| 
60b098bb8b8a
heavily revised by Jacques: coercions have alphabetic names;
 paulson parents: 
6073diff
changeset | 653 | Addsimps [pnat_of_nat_less_iff RS sym]; | 
| 5078 | 654 | |
| 9422 | 655 | Goalw [pnat_mult_def,pnat_of_nat_def] | 
| 7292 | 656 | "pnat_of_nat n1 * pnat_of_nat n2 = \ | 
| 657 | \ pnat_of_nat (n1 * n2 + n1 + n2)"; | |
| 658 | by (auto_tac (claset(),simpset() addsimps [mult_Rep_pnat_mult, | |
| 659 | pnat_add_def,Abs_pnat_inverse,gt_0_mem_pnat])); | |
| 660 | qed "pnat_of_nat_mult"; |