# HG changeset patch # User nipkow # Date 915458867 -3600 # Node ID fdf4638bf7263f88d242e90031edbbe345d7b4c9 # Parent 4a4f6ad607a1de09bb6511af8c13302099687d64 Version 1.0 of linear nat arithmetic. diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/Arith.ML --- a/src/HOL/Arith.ML Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/Arith.ML Mon Jan 04 15:07:47 1999 +0100 @@ -626,6 +626,7 @@ signature ARITH_DATA = sig + val nat_cancel_sums_add: simproc list val nat_cancel_sums: simproc list val nat_cancel_factor: simproc list val nat_cancel: simproc list @@ -816,11 +817,13 @@ val le_pats = prep_pats ["(l::nat) + m <= n", "(l::nat) <= m + n", "Suc m <= n", "m <= Suc n"]; val diff_pats = prep_pats ["((l::nat) + m) - n", "(l::nat) - (m + n)", "Suc m - n", "m - Suc n"]; -val nat_cancel_sums = map prep_simproc +val nat_cancel_sums_add = map prep_simproc [("nateq_cancel_sums", eq_pats, EqCancelSums.proc), ("natless_cancel_sums", less_pats, LessCancelSums.proc), - ("natle_cancel_sums", le_pats, LeCancelSums.proc), - ("natdiff_cancel_sums", diff_pats, DiffCancelSums.proc)]; + ("natle_cancel_sums", le_pats, LeCancelSums.proc)]; + +val nat_cancel_sums = nat_cancel_sums_add @ + [prep_simproc("natdiff_cancel_sums", diff_pats, DiffCancelSums.proc)]; val nat_cancel_factor = map prep_simproc [("nateq_cancel_factor", eq_pats, EqCancelFactor.proc), @@ -853,8 +856,9 @@ val sym = sym; val nat = Type("nat",[]); +val boolT = Type("bool",[]); -fun nnb T = T = Type("fun",[nat,Type("fun",[nat,Type("bool",[])])]) +fun nnb T = T = ([nat,nat] ---> boolT); (* Turn term into list of summand * multiplicity plus a constant *) fun poly(Const("Suc",_)$t, (p,i)) = poly(t, (p,i+1)) @@ -882,13 +886,14 @@ | decomp(_$(Const("Not",_)$(Const(rel,T)$lhs$rhs))) = negate(decomp2(rel,T,lhs,rhs)) | decomp _ = None + (* reduce contradictory <= to False. Most of the work is done by the cancel tactics. *) val add_rules = [Zero_not_Suc,Suc_not_Zero,le_0_eq]; val cancel_sums_ss = HOL_basic_ss addsimps add_rules - addsimprocs nat_cancel_sums; + addsimprocs nat_cancel_sums_add; val simp = simplify cancel_sums_ss; @@ -896,129 +901,120 @@ (fn prems => [cut_facts_tac prems 1, blast_tac (claset() addIs [add_le_mono]) 1])) ["(i <= j) & (k <= l) ==> i + k <= j + (l::nat)", - "(i = j) & (k <= l) ==> i + k <= j + (l::nat)", - "(i <= j) & (k = l) ==> i + k <= j + (l::nat)", - "(i = j) & (k = l) ==> i + k <= j + (l::nat)" + "(i = j) & (k <= l) ==> i + k <= j + (l::nat)", + "(i <= j) & (k = l) ==> i + k <= j + (l::nat)", + "(i = j) & (k = l) ==> i + k = j + (l::nat)" ]; +fun is_False thm = + let val _ $ t = #prop(rep_thm thm) + in t = Const("False",boolT) end; + +fun is_nat(t) = fastype_of1 t = nat; + +fun mk_nat_thm sg t = + let val ct = cterm_of sg t and cn = cterm_of sg (Var(("n",0),nat)) + in instantiate ([],[(cn,ct)]) le0 end; + end; structure Fast_Nat_Arith = Fast_Lin_Arith(Nat_LA_Data); simpset_ref () := (simpset() addSolver Fast_Nat_Arith.cut_lin_arith_tac); +val fast_nat_arith_tac = Fast_Nat_Arith.lin_arith_tac; + +(* Elimination of `-' on nat due to John Harrison *) +Goal "P(a - b::nat) = (!d. (b = a + d --> P 0) & (a = b + d --> P d))"; +by(case_tac "a <= b" 1); +by(Auto_tac); +by(eres_inst_tac [("x","b-a")] allE 1); +by(Auto_tac); +qed "nat_diff_split"; + +(* FIXME: K true should be replaced by a sensible test to speed things up + in case there are lots of irrelevant terms involved +*) +val nat_arith_tac = + refute_tac (K true) (REPEAT o split_tac[nat_diff_split]) + ((REPEAT o etac nat_neqE) THEN' fast_nat_arith_tac); + (*---------------------------------------------------------------------------*) (* End of proof procedures. Now go and USE them! *) (*---------------------------------------------------------------------------*) - (*** Subtraction laws -- mostly from Clemens Ballarin ***) Goal "[| a < (b::nat); c <= a |] ==> a-c < b-c"; -by (subgoal_tac "c+(a-c) < c+(b-c)" 1); -by (Full_simp_tac 1); -by (subgoal_tac "c <= b" 1); -by (blast_tac (claset() addIs [less_imp_le, le_trans]) 2); -by (Asm_simp_tac 1); +by(nat_arith_tac 1); qed "diff_less_mono"; Goal "a+b < (c::nat) ==> a < c-b"; -by (dtac diff_less_mono 1); -by (rtac le_add2 1); -by (Asm_full_simp_tac 1); +by(nat_arith_tac 1); qed "add_less_imp_less_diff"; Goal "(i < j-k) = (i+k < (j::nat))"; -by (rtac iffI 1); - by (case_tac "k <= j" 1); - by (dtac le_add_diff_inverse2 1); - by (dres_inst_tac [("k","k")] add_less_mono1 1); - by (Asm_full_simp_tac 1); - by (rotate_tac 1 1); - by (Asm_full_simp_tac 1); -by (etac add_less_imp_less_diff 1); +by(nat_arith_tac 1); qed "less_diff_conv"; Goal "(j-k <= (i::nat)) = (j <= i+k)"; -by (simp_tac (simpset() addsimps [less_diff_conv, le_def]) 1); +by(nat_arith_tac 1); qed "le_diff_conv"; Goal "k <= j ==> (i <= j-k) = (i+k <= (j::nat))"; -by (asm_full_simp_tac - (simpset() delsimps [less_Suc_eq_le] - addsimps [less_Suc_eq_le RS sym, less_diff_conv, - Suc_diff_le RS sym]) 1); +by(nat_arith_tac 1); qed "le_diff_conv2"; Goal "Suc i <= n ==> Suc (n - Suc i) = n - i"; -by (asm_full_simp_tac (simpset() addsimps [Suc_diff_le RS sym]) 1); +by(nat_arith_tac 1); qed "Suc_diff_Suc"; Goal "i <= (n::nat) ==> n - (n - i) = i"; -by (etac rev_mp 1); -by (res_inst_tac [("m","n"),("n","i")] diff_induct 1); -by (ALLGOALS (asm_simp_tac (simpset() addsimps [Suc_diff_le]))); +by(nat_arith_tac 1); qed "diff_diff_cancel"; Addsimps [diff_diff_cancel]; Goal "k <= (n::nat) ==> m <= n + m - k"; -by (etac rev_mp 1); -by (res_inst_tac [("m", "k"), ("n", "n")] diff_induct 1); -by (Simp_tac 1); -by (simp_tac (simpset() addsimps [le_add2, less_imp_le]) 1); -by (Simp_tac 1); +by(nat_arith_tac 1); qed "le_add_diff"; -Goal "0 j j+k-i < k"; -by (res_inst_tac [("m","j"),("n","i")] diff_induct 1); -by (ALLGOALS Asm_simp_tac); -qed_spec_mp "add_diff_less"; - +Goal "[| 0 j+k-i < k"; +by(nat_arith_tac 1); +qed "add_diff_less"; Goal "m-1 < n ==> m <= n"; -by (exhaust_tac "m" 1); -by (auto_tac (claset(), simpset() addsimps [Suc_le_eq])); +by(nat_arith_tac 1); qed "pred_less_imp_le"; Goal "j<=i ==> i - j < Suc i - j"; -by (REPEAT (etac rev_mp 1)); -by (res_inst_tac [("m","i"),("n","j")] diff_induct 1); -by Auto_tac; +by(nat_arith_tac 1); qed "diff_less_Suc_diff"; Goal "i - j <= Suc i - j"; -by (res_inst_tac [("m","i"),("n","j")] diff_induct 1); -by Auto_tac; +by(nat_arith_tac 1); qed "diff_le_Suc_diff"; AddIffs [diff_le_Suc_diff]; Goal "n - Suc i <= n - i"; -by (case_tac "i (m <= n-1) = (m (m-1 < n) = (m<=n)"; -by (exhaust_tac "m" 1); -by (auto_tac (claset(), simpset() addsimps [Suc_le_eq])); +by(nat_arith_tac 1); qed "less_pred_eq"; (*In ordinary notation: if 0 m - n < m"; -by (subgoal_tac "0 ~ m m - n < m" 1); -by (Blast_tac 1); -by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); -by (ALLGOALS(asm_simp_tac(simpset() addsimps [diff_less_Suc]))); +by(nat_arith_tac 1); qed "diff_less"; Goal "[| 0 m - n < m"; -by (asm_simp_tac (simpset() addsimps [diff_less, not_less_iff_le]) 1); +by(nat_arith_tac 1); qed "le_diff_less"; @@ -1026,52 +1022,20 @@ (** (Anti)Monotonicity of subtraction -- by Stefan Merz **) (* Monotonicity of subtraction in first argument *) -Goal "m <= (n::nat) --> (m-l) <= (n-l)"; -by (induct_tac "n" 1); -by (Simp_tac 1); -by (simp_tac (simpset() addsimps [le_Suc_eq]) 1); -by (blast_tac (claset() addIs [diff_le_Suc_diff, le_trans]) 1); -qed_spec_mp "diff_le_mono"; +Goal "m <= (n::nat) ==> (m-l) <= (n-l)"; +by(nat_arith_tac 1); +qed "diff_le_mono"; Goal "m <= (n::nat) ==> (l-n) <= (l-m)"; -by (induct_tac "l" 1); -by (Simp_tac 1); -by (case_tac "n <= na" 1); -by (subgoal_tac "m <= na" 1); -by (asm_simp_tac (simpset() addsimps [Suc_diff_le]) 1); -by (fast_tac (claset() addEs [le_trans]) 1); -by (dtac not_leE 1); -by (asm_simp_tac (simpset() addsimps [if_Suc_diff_le]) 1); -qed_spec_mp "diff_le_mono2"; +by(nat_arith_tac 1); +qed "diff_le_mono2"; (*This proof requires natdiff_cancel_sums*) -Goal "m < (n::nat) --> m (l-n) < (l-m)"; -by (induct_tac "l" 1); -by (Simp_tac 1); -by (Clarify_tac 1); -by (etac less_SucE 1); -by (Clarify_tac 2); -by (asm_simp_tac (simpset() addsimps [Suc_le_eq]) 2); -by (asm_simp_tac (simpset() addsimps [diff_Suc_le_Suc_diff RS le_less_trans, - Suc_diff_le, less_imp_le]) 1); -qed_spec_mp "diff_less_mono2"; - -(** Elimination of `-' on nat due to John Harrison **) -(*This proof requires natle_cancel_sums*) +Goal "[| m < (n::nat); m (l-n) < (l-m)"; +by(nat_arith_tac 1); +qed "diff_less_mono2"; -Goal "P(a - b::nat) = (!d. (b = a + d --> P 0) & (a = b + d --> P d))"; -by(case_tac "a <= b" 1); -by(Auto_tac); -by(eres_inst_tac [("x","b-a")] allE 1); -by(Auto_tac); -qed "nat_diff_split"; - -(* -This is an example of the power of nat_diff_split. Many of the `-' thms in -Arith.ML could take advantage of this, but would need to be moved. -*) -Goal "m-n = 0 --> n-m = 0 --> m=n"; -by(simp_tac (simpset() addsplits [nat_diff_split]) 1); -qed_spec_mp "diffs0_imp_equal"; - +Goal "[| m-n = 0; n-m = 0 |] ==> m=n"; +by(nat_arith_tac 1); +qed "diffs0_imp_equal"; diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/Hoare/Hoare.thy --- a/src/HOL/Hoare/Hoare.thy Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/Hoare/Hoare.thy Mon Jan 04 15:07:47 1999 +0100 @@ -18,12 +18,12 @@ datatype 'a com = Basic ('a fexp) - | Seq ('a com) ('a com) ("(_;/_)" [61,60] 60) + | Seq ('a com) ('a com) ("(_;/ _)" [61,60] 60) | Cond ('a bexp) ('a com) ('a com) ("(1IF _/ THEN _ / ELSE _/ FI)" [0,0,0] 61) | While ('a bexp) ('a assn) ('a com) ("(1WHILE _/ INV {_} //DO _ /OD)" [0,0,0] 61) syntax - "@assign" :: id => 'b => 'a com ("(2_ :=/ _ )" [70,65] 61) + "@assign" :: id => 'b => 'a com ("(2_ :=/ _)" [70,65] 61) "@annskip" :: 'a com ("SKIP") translations diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/IsaMakefile --- a/src/HOL/IsaMakefile Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/IsaMakefile Mon Jan 04 15:07:47 1999 +0100 @@ -55,7 +55,7 @@ Tools/inductive_package.ML Tools/primrec_package.ML \ Tools/record_package.ML Tools/typedef_package.ML Trancl.ML \ Trancl.thy Univ.ML Univ.thy Vimage.ML Vimage.thy WF.ML WF.thy \ - WF_Rel.ML WF_Rel.thy arith_data.ML cladata.ML equalities.ML \ + WF_Rel.ML WF_Rel.thy cladata.ML equalities.ML \ equalities.thy hologic.ML mono.ML mono.thy simpdata.ML subset.ML \ subset.thy thy_syntax.ML @$(ISATOOL) usedir -b $(OUT)/Pure HOL diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/Lambda/Lambda.ML --- a/src/HOL/Lambda/Lambda.ML Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/Lambda/Lambda.ML Mon Jan 04 15:07:47 1999 +0100 @@ -110,7 +110,6 @@ Goal "!k. liftn (Suc n) t k = lift (liftn n t k) k"; by (induct_tac "t" 1); by (ALLGOALS(asm_simp_tac(addsplit(simpset())))); -by (blast_tac (claset() addDs [add_lessD1]) 1); qed "liftn_lift"; Addsimps [liftn_lift]; diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/Lambda/ListApplication.ML --- a/src/HOL/Lambda/ListApplication.ML Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/Lambda/ListApplication.ML Mon Jan 04 15:07:47 1999 +0100 @@ -88,14 +88,7 @@ Addsimps [size_apps]; Goal "[| 0 < k; m <= n |] ==> m < n+k"; -by (exhaust_tac "k" 1); - by (Asm_full_simp_tac 1); -by (Asm_full_simp_tac 1); -by (rtac le_imp_less_Suc 1); -by (exhaust_tac "n" 1); - by (Asm_full_simp_tac 1); -by (hyp_subst_tac 1); -by (etac trans_le_add1 1); +by(fast_nat_arith_tac 1); val lemma = result(); (* a customized induction schema for $$ *) diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/List.ML --- a/src/HOL/List.ML Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/List.ML Mon Jan 04 15:07:47 1999 +0100 @@ -858,7 +858,6 @@ by (induct_tac "ns" 1); by (Simp_tac 1); by (Asm_full_simp_tac 1); -by (blast_tac (claset() addIs [trans_le_add1]) 1); qed_spec_mp "start_le_sum"; Goal "n : set ns ==> n <= foldl op+ 0 ns"; diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/UNITY/Token.ML --- a/src/HOL/UNITY/Token.ML Mon Dec 28 17:03:47 1998 +0100 +++ b/src/HOL/UNITY/Token.ML Mon Jan 04 15:07:47 1999 +0100 @@ -61,8 +61,6 @@ simpset() addsimps [diff_add_assoc2, linorder_neq_iff, Suc_le_eq, Suc_diff_Suc, less_imp_diff_less, add_diff_less, mod_less, mod_geq])); -by (etac subst 1); -by (asm_simp_tac (simpset() addsimps [add_diff_less]) 1); qed "nodeOrder_eq"; diff -r 4a4f6ad607a1 -r fdf4638bf726 src/HOL/arith_data.ML --- a/src/HOL/arith_data.ML Mon Dec 28 17:03:47 1998 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -(* Title: HOL/arith_data.ML - ID: $Id$ - Author: Markus Wenzel and Stefan Berghofer, TU Muenchen - -Setup various arithmetic proof procedures. -*) - -signature ARITH_DATA = -sig - val nat_cancel_sums: simproc list - val nat_cancel_factor: simproc list - val nat_cancel: simproc list -end; - -structure ArithData: ARITH_DATA = -struct - - -(** abstract syntax of structure nat: 0, Suc, + **) - -(* mk_sum, mk_norm_sum *) - -val one = HOLogic.mk_nat 1; -val mk_plus = HOLogic.mk_binop "op +"; - -fun mk_sum [] = HOLogic.zero - | mk_sum [t] = t - | mk_sum (t :: ts) = mk_plus (t, mk_sum ts); - -(*normal form of sums: Suc (... (Suc (a + (b + ...))))*) -fun mk_norm_sum ts = - let val (ones, sums) = partition (equal one) ts in - funpow (length ones) HOLogic.mk_Suc (mk_sum sums) - end; - - -(* dest_sum *) - -val dest_plus = HOLogic.dest_bin "op +" HOLogic.natT; - -fun dest_sum tm = - if HOLogic.is_zero tm then [] - else - (case try HOLogic.dest_Suc tm of - Some t => one :: dest_sum t - | None => - (case try dest_plus tm of - Some (t, u) => dest_sum t @ dest_sum u - | None => [tm])); - - -(** generic proof tools **) - -(* prove conversions *) - -val mk_eqv = HOLogic.mk_Trueprop o HOLogic.mk_eq; - -fun prove_conv expand_tac norm_tac sg (t, u) = - mk_meta_eq (prove_goalw_cterm_nocheck [] (cterm_of sg (mk_eqv (t, u))) - (K [expand_tac, norm_tac])) - handle ERROR => error ("The error(s) above occurred while trying to prove " ^ - (string_of_cterm (cterm_of sg (mk_eqv (t, u))))); - -val subst_equals = prove_goal HOL.thy "[| t = s; u = t |] ==> u = s" - (fn prems => [cut_facts_tac prems 1, SIMPSET' asm_simp_tac 1]); - - -(* rewriting *) - -fun simp_all rules = ALLGOALS (simp_tac (HOL_ss addsimps rules)); - -val add_rules = [add_Suc, add_Suc_right, add_0, add_0_right]; -val mult_rules = [mult_Suc, mult_Suc_right, mult_0, mult_0_right]; - - - -(** cancel common summands **) - -structure Sum = -struct - val mk_sum = mk_norm_sum; - val dest_sum = dest_sum; - val prove_conv = prove_conv; - val norm_tac = simp_all add_rules THEN simp_all add_ac; -end; - -fun gen_uncancel_tac rule ct = - rtac (instantiate' [] [None, Some ct] (rule RS subst_equals)) 1; - - -(* nat eq *) - -structure EqCancelSums = CancelSumsFun -(struct - open Sum; - val mk_bal = HOLogic.mk_eq; - val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT; - val uncancel_tac = gen_uncancel_tac add_left_cancel; -end); - - -(* nat less *) - -structure LessCancelSums = CancelSumsFun -(struct - open Sum; - val mk_bal = HOLogic.mk_binrel "op <"; - val dest_bal = HOLogic.dest_bin "op <" HOLogic.natT; - val uncancel_tac = gen_uncancel_tac add_left_cancel_less; -end); - - -(* nat le *) - -structure LeCancelSums = CancelSumsFun -(struct - open Sum; - val mk_bal = HOLogic.mk_binrel "op <="; - val dest_bal = HOLogic.dest_bin "op <=" HOLogic.natT; - val uncancel_tac = gen_uncancel_tac add_left_cancel_le; -end); - - -(* nat diff *) - -structure DiffCancelSums = CancelSumsFun -(struct - open Sum; - val mk_bal = HOLogic.mk_binop "op -"; - val dest_bal = HOLogic.dest_bin "op -" HOLogic.natT; - val uncancel_tac = gen_uncancel_tac diff_cancel; -end); - - - -(** cancel common factor **) - -structure Factor = -struct - val mk_sum = mk_norm_sum; - val dest_sum = dest_sum; - val prove_conv = prove_conv; - val norm_tac = simp_all (add_rules @ mult_rules) THEN simp_all add_ac; -end; - -fun mk_cnat n = cterm_of (sign_of Nat.thy) (HOLogic.mk_nat n); - -fun gen_multiply_tac rule k = - if k > 0 then - rtac (instantiate' [] [None, Some (mk_cnat (k - 1))] (rule RS subst_equals)) 1 - else no_tac; - - -(* nat eq *) - -structure EqCancelFactor = CancelFactorFun -(struct - open Factor; - val mk_bal = HOLogic.mk_eq; - val dest_bal = HOLogic.dest_bin "op =" HOLogic.natT; - val multiply_tac = gen_multiply_tac Suc_mult_cancel1; -end); - - -(* nat less *) - -structure LessCancelFactor = CancelFactorFun -(struct - open Factor; - val mk_bal = HOLogic.mk_binrel "op <"; - val dest_bal = HOLogic.dest_bin "op <" HOLogic.natT; - val multiply_tac = gen_multiply_tac Suc_mult_less_cancel1; -end); - - -(* nat le *) - -structure LeCancelFactor = CancelFactorFun -(struct - open Factor; - val mk_bal = HOLogic.mk_binrel "op <="; - val dest_bal = HOLogic.dest_bin "op <=" HOLogic.natT; - val multiply_tac = gen_multiply_tac Suc_mult_le_cancel1; -end); - - - -(** prepare nat_cancel simprocs **) - -fun prep_pat s = Thm.read_cterm (sign_of Arith.thy) (s, HOLogic.termTVar); -val prep_pats = map prep_pat; - -fun prep_simproc (name, pats, proc) = Simplifier.mk_simproc name pats proc; - -val eq_pats = prep_pats ["(l::nat) + m = n", "(l::nat) = m + n", "Suc m = n", "m = Suc n"]; -val less_pats = prep_pats ["(l::nat) + m < n", "(l::nat) < m + n", "Suc m < n", "m < Suc n"]; -val le_pats = prep_pats ["(l::nat) + m <= n", "(l::nat) <= m + n", "Suc m <= n", "m <= Suc n"]; -val diff_pats = prep_pats ["((l::nat) + m) - n", "(l::nat) - (m + n)", "Suc m - n", "m - Suc n"]; - -val nat_cancel_sums = map prep_simproc - [("nateq_cancel_sums", eq_pats, EqCancelSums.proc), - ("natless_cancel_sums", less_pats, LessCancelSums.proc), - ("natle_cancel_sums", le_pats, LeCancelSums.proc), - ("natdiff_cancel_sums", diff_pats, DiffCancelSums.proc)]; - -val nat_cancel_factor = map prep_simproc - [("nateq_cancel_factor", eq_pats, EqCancelFactor.proc), - ("natless_cancel_factor", less_pats, LessCancelFactor.proc), - ("natle_cancel_factor", le_pats, LeCancelFactor.proc)]; - -val nat_cancel = nat_cancel_factor @ nat_cancel_sums; - - -end; - - -open ArithData; - - -context Arith.thy; -Addsimprocs nat_cancel; - - -(*This proof requires natdiff_cancel_sums*) -Goal "m < (n::nat) --> m (l-n) < (l-m)"; -by (induct_tac "l" 1); -by (Simp_tac 1); -by (Clarify_tac 1); -by (etac less_SucE 1); -by (Clarify_tac 2); -by (asm_simp_tac (simpset() addsimps [Suc_le_eq]) 2); -by (asm_simp_tac (simpset() addsimps [diff_Suc_le_Suc_diff RS le_less_trans, - Suc_diff_le, less_imp_le]) 1); -qed_spec_mp "diff_less_mono2"; - -(** Elimination of - on nat due to John Harrison **) -(*This proof requires natle_cancel_sums*) - -Goal "P(a - b::nat) = (!d. (b = a + d --> P 0) & (a = b + d --> P d))"; -by(case_tac "a <= b" 1); -by(Auto_tac); -by(eres_inst_tac [("x","b-a")] allE 1); -by(Auto_tac); -qed "nat_diff_split"; - -(* -This is an example of the power of nat_diff_split. Many of the `-' thms in -Arith.ML could take advantage of this, but would need to be moved. -*) -Goal "m-n = 0 --> n-m = 0 --> m=n"; -by(simp_tac (simpset() addsplits [nat_diff_split]) 1); -qed_spec_mp "diffs0_imp_equal"; - -use"fast_nat_decider"; - -simpset_ref () := (simpset() addSolver - (fn thms => cut_facts_tac thms THEN' Fast_Nat_Decider.nat_arith_tac));