323 qed_goal "diff_self_eq_0" Arith.thy "m - m = 0" |
323 qed_goal "diff_self_eq_0" Arith.thy "m - m = 0" |
324 (fn _ => [induct_tac "m" 1, ALLGOALS Asm_simp_tac]); |
324 (fn _ => [induct_tac "m" 1, ALLGOALS Asm_simp_tac]); |
325 Addsimps [diff_self_eq_0]; |
325 Addsimps [diff_self_eq_0]; |
326 |
326 |
327 (*Addition is the inverse of subtraction: if n<=m then n+(m-n) = m. *) |
327 (*Addition is the inverse of subtraction: if n<=m then n+(m-n) = m. *) |
328 val [prem] = goal Arith.thy "[| ~ m<n |] ==> n+(m-n) = (m::nat)"; |
328 val [prem] = goal Arith.thy "~ m<n ==> n+(m-n) = (m::nat)"; |
329 by (rtac (prem RS rev_mp) 1); |
329 by (rtac (prem RS rev_mp) 1); |
330 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
330 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
331 by (ALLGOALS (Asm_simp_tac)); |
331 by (ALLGOALS Asm_simp_tac); |
332 qed "add_diff_inverse"; |
332 qed "add_diff_inverse"; |
333 |
333 |
334 Delsimps [diff_Suc]; |
334 Delsimps [diff_Suc]; |
335 |
335 |
336 |
336 |
337 (*** More results about difference ***) |
337 (*** More results about difference ***) |
|
338 |
|
339 val [prem] = goal Arith.thy "n < Suc(m) ==> Suc(m)-n = Suc(m-n)"; |
|
340 by (rtac (prem RS rev_mp) 1); |
|
341 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
|
342 by (ALLGOALS Asm_simp_tac); |
|
343 qed "Suc_diff_n"; |
338 |
344 |
339 goal Arith.thy "m - n < Suc(m)"; |
345 goal Arith.thy "m - n < Suc(m)"; |
340 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
346 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
341 by (etac less_SucE 3); |
347 by (etac less_SucE 3); |
342 by (ALLGOALS (asm_simp_tac (!simpset addsimps [less_Suc_eq]))); |
348 by (ALLGOALS (asm_simp_tac (!simpset addsimps [less_Suc_eq]))); |
345 goal Arith.thy "!!m::nat. m - n <= m"; |
351 goal Arith.thy "!!m::nat. m - n <= m"; |
346 by (res_inst_tac [("m","m"), ("n","n")] diff_induct 1); |
352 by (res_inst_tac [("m","m"), ("n","n")] diff_induct 1); |
347 by (ALLGOALS Asm_simp_tac); |
353 by (ALLGOALS Asm_simp_tac); |
348 qed "diff_le_self"; |
354 qed "diff_le_self"; |
349 |
355 |
|
356 goal Arith.thy "!!i::nat. i-j-k = i - (j+k)"; |
|
357 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1); |
|
358 by (ALLGOALS Asm_simp_tac); |
|
359 qed "diff_diff_left"; |
|
360 |
|
361 (*This and the next few suggested by Florian Kammüller*) |
|
362 goal Arith.thy "!!i::nat. i-j-k = i-k-j"; |
|
363 by (simp_tac (!simpset addsimps [diff_diff_left, add_commute]) 1); |
|
364 qed "diff_commute"; |
|
365 |
|
366 goal Arith.thy "!!i j k:: nat. k<=j --> j<=i --> i - (j - k) = i - j + k"; |
|
367 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1); |
|
368 by (ALLGOALS Asm_simp_tac); |
|
369 by (asm_simp_tac |
|
370 (!simpset addsimps [Suc_diff_n, le_imp_less_Suc, le_Suc_eq]) 1); |
|
371 by (simp_tac |
|
372 (!simpset addsimps [add_diff_inverse, not_less_iff_le, add_commute]) 1); |
|
373 qed_spec_mp "diff_diff_right"; |
|
374 |
|
375 goal Arith.thy "!!i j k:: nat. k<=j --> (i + j) - k = i + (j - k)"; |
|
376 by (res_inst_tac [("m","j"),("n","k")] diff_induct 1); |
|
377 by (ALLGOALS Asm_simp_tac); |
|
378 qed_spec_mp "diff_add_assoc"; |
|
379 |
350 goal Arith.thy "!!n::nat. (n+m) - n = m"; |
380 goal Arith.thy "!!n::nat. (n+m) - n = m"; |
351 by (induct_tac "n" 1); |
381 by (induct_tac "n" 1); |
352 by (ALLGOALS Asm_simp_tac); |
382 by (ALLGOALS Asm_simp_tac); |
353 qed "diff_add_inverse"; |
383 qed "diff_add_inverse"; |
354 Addsimps [diff_add_inverse]; |
384 Addsimps [diff_add_inverse]; |
355 |
385 |
356 goal Arith.thy "!!n::nat.(m+n) - n = m"; |
386 goal Arith.thy "!!n::nat.(m+n) - n = m"; |
357 by (res_inst_tac [("m1","m")] (add_commute RS ssubst) 1); |
387 by (simp_tac (!simpset addsimps [diff_add_assoc]) 1); |
358 by (REPEAT (ares_tac [diff_add_inverse] 1)); |
|
359 qed "diff_add_inverse2"; |
388 qed "diff_add_inverse2"; |
360 Addsimps [diff_add_inverse2]; |
389 Addsimps [diff_add_inverse2]; |
361 |
390 |
362 val [prem] = goal Arith.thy "m < Suc(n) ==> m-n = 0"; |
391 val [prem] = goal Arith.thy "m < Suc(n) ==> m-n = 0"; |
363 by (rtac (prem RS rev_mp) 1); |
392 by (rtac (prem RS rev_mp) 1); |
364 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
393 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
365 by (asm_simp_tac (!simpset addsimps [less_Suc_eq]) 1); |
394 by (asm_simp_tac (!simpset addsimps [less_Suc_eq]) 1); |
366 by (ALLGOALS (Asm_simp_tac)); |
395 by (ALLGOALS Asm_simp_tac); |
367 qed "less_imp_diff_is_0"; |
396 qed "less_imp_diff_is_0"; |
368 |
397 |
369 val prems = goal Arith.thy "m-n = 0 --> n-m = 0 --> m=n"; |
398 val prems = goal Arith.thy "m-n = 0 --> n-m = 0 --> m=n"; |
370 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
399 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
371 by (REPEAT(Simp_tac 1 THEN TRY(atac 1))); |
400 by (REPEAT(Simp_tac 1 THEN TRY(atac 1))); |
372 qed_spec_mp "diffs0_imp_equal"; |
401 qed_spec_mp "diffs0_imp_equal"; |
373 |
402 |
374 val [prem] = goal Arith.thy "m<n ==> 0<n-m"; |
403 val [prem] = goal Arith.thy "m<n ==> 0<n-m"; |
375 by (rtac (prem RS rev_mp) 1); |
404 by (rtac (prem RS rev_mp) 1); |
376 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
405 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
377 by (ALLGOALS (Asm_simp_tac)); |
406 by (ALLGOALS Asm_simp_tac); |
378 qed "less_imp_diff_positive"; |
407 qed "less_imp_diff_positive"; |
379 |
|
380 val [prem] = goal Arith.thy "n < Suc(m) ==> Suc(m)-n = Suc(m-n)"; |
|
381 by (rtac (prem RS rev_mp) 1); |
|
382 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
|
383 by (ALLGOALS (Asm_simp_tac)); |
|
384 qed "Suc_diff_n"; |
|
385 |
408 |
386 goal Arith.thy "Suc(m)-n = (if m<n then 0 else Suc(m-n))"; |
409 goal Arith.thy "Suc(m)-n = (if m<n then 0 else Suc(m-n))"; |
387 by (simp_tac (!simpset addsimps [less_imp_diff_is_0, not_less_eq, Suc_diff_n] |
410 by (simp_tac (!simpset addsimps [less_imp_diff_is_0, not_less_eq, Suc_diff_n] |
388 setloop (split_tac [expand_if])) 1); |
411 setloop (split_tac [expand_if])) 1); |
389 qed "if_Suc_diff_n"; |
412 qed "if_Suc_diff_n"; |