853 val notI = notI; |
853 val notI = notI; |
854 val not_leD = not_leE RS Suc_leI; |
854 val not_leD = not_leE RS Suc_leI; |
855 val not_lessD = leI; |
855 val not_lessD = leI; |
856 val sym = sym; |
856 val sym = sym; |
857 |
857 |
|
858 fun mkEqTrue thm = thm RS (eqTrueI RS eq_reflection); |
|
859 val mk_Trueprop = HOLogic.mk_Trueprop; |
|
860 |
|
861 fun neg_prop(TP$(Const("Not",_)$t)) = (TP$t, true) |
|
862 | neg_prop(TP$t) = |
|
863 (TP $ (Const("Not",HOLogic.boolT-->HOLogic.boolT)$t), false); |
|
864 |
858 (* Turn term into list of summand * multiplicity plus a constant *) |
865 (* Turn term into list of summand * multiplicity plus a constant *) |
859 fun poly(Const("Suc",_)$t, (p,i)) = poly(t, (p,i+1)) |
866 fun poly(Const("Suc",_)$t, (p,i)) = poly(t, (p,i+1)) |
860 | poly(Const("op +",_) $ s $ t, pi) = poly(s,poly(t,pi)) |
867 | poly(Const("op +",_) $ s $ t, pi) = poly(s,poly(t,pi)) |
861 | poly(t,(p,i)) = |
868 | poly(t,(p,i)) = |
862 if t = Const("0",HOLogic.natT) then (p,i) |
869 if t = Const("0",HOLogic.natT) then (p,i) |
914 |
921 |
915 end; |
922 end; |
916 |
923 |
917 structure Fast_Nat_Arith = Fast_Lin_Arith(Nat_LA_Data); |
924 structure Fast_Nat_Arith = Fast_Lin_Arith(Nat_LA_Data); |
918 |
925 |
|
926 val fast_nat_arith_tac = Fast_Nat_Arith.lin_arith_tac; |
|
927 |
|
928 local |
|
929 fun prep_pat s = Thm.read_cterm (sign_of Arith.thy) (s, HOLogic.boolT); |
|
930 |
|
931 val pats = map prep_pat |
|
932 ["(m::nat) < n","(m::nat) <= n", "~ (m::nat) < n","~ (m::nat) <= n", |
|
933 "(m::nat) = n"] |
|
934 |
|
935 in |
|
936 val fast_nat_arith_simproc = |
|
937 mk_simproc "fast_nat_arith" pats Fast_Nat_Arith.lin_arith_prover; |
|
938 end; |
|
939 |
|
940 Addsimprocs [fast_nat_arith_simproc]; |
|
941 |
|
942 (* Because of fast_nat_arith_simproc, the arithmetic solver is really only |
|
943 useful to detect inconsistencies among the premises for subgoals which are |
|
944 *not* themselves (in)equalities, because the latter activate |
|
945 fast_nat_arith_simproc anyway. However, it seems cheaper to activate the |
|
946 solver all the time rather than add the additional check. *) |
|
947 |
919 simpset_ref () := (simpset() addSolver Fast_Nat_Arith.cut_lin_arith_tac); |
948 simpset_ref () := (simpset() addSolver Fast_Nat_Arith.cut_lin_arith_tac); |
920 |
|
921 val fast_nat_arith_tac = Fast_Nat_Arith.lin_arith_tac; |
|
922 |
949 |
923 (* Elimination of `-' on nat due to John Harrison *) |
950 (* Elimination of `-' on nat due to John Harrison *) |
924 Goal "P(a - b::nat) = (!d. (b = a + d --> P 0) & (a = b + d --> P d))"; |
951 Goal "P(a - b::nat) = (!d. (b = a + d --> P 0) & (a = b + d --> P d))"; |
925 by(case_tac "a <= b" 1); |
952 by(case_tac "a <= b" 1); |
926 by(Auto_tac); |
953 by(Auto_tac); |