diff -r 3470596f3cd5 -r 3196f93030bb src/HOL/NatDef.ML --- a/src/HOL/NatDef.ML Mon Aug 05 12:00:51 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,469 +0,0 @@ -(* Title: HOL/NatDef.ML - ID: $Id$ - Author: Tobias Nipkow, Cambridge University Computer Laboratory - Copyright 1991 University of Cambridge -*) - -Addsimps [One_nat_def]; - -val rew = rewrite_rule [symmetric Nat_def]; - -(*** Induction ***) - -val prems = Goalw [Zero_nat_def,Suc_def] - "[| P(0); \ -\ !!n. P(n) ==> P(Suc(n)) |] ==> P(n)"; -by (rtac (Rep_Nat_inverse RS subst) 1); (*types force good instantiation*) -by (rtac (Rep_Nat RS rew Nat'.induct) 1); -by (REPEAT (ares_tac prems 1 - ORELSE eresolve_tac [Abs_Nat_inverse RS subst] 1)); -qed "nat_induct"; - -(*Perform induction on n. *) -fun nat_ind_tac a i = - res_inst_tac [("n",a)] nat_induct i THEN rename_last_tac a [""] (i+1); - -(*A special form of induction for reasoning about m P (Suc x) (Suc y) \ -\ |] ==> P m n"; -by (res_inst_tac [("x","m")] spec 1); -by (nat_ind_tac "n" 1); -by (rtac allI 2); -by (nat_ind_tac "x" 2); -by (REPEAT (ares_tac (prems@[allI]) 1 ORELSE etac spec 1)); -qed "diff_induct"; - -(*** Isomorphisms: Abs_Nat and Rep_Nat ***) - -(*We can't take these properties as axioms, or take Abs_Nat==Inv(Rep_Nat), - since we assume the isomorphism equations will one day be given by Isabelle*) - -Goal "inj(Rep_Nat)"; -by (rtac inj_inverseI 1); -by (rtac Rep_Nat_inverse 1); -qed "inj_Rep_Nat"; - -Goal "inj_on Abs_Nat Nat"; -by (rtac inj_on_inverseI 1); -by (etac Abs_Nat_inverse 1); -qed "inj_on_Abs_Nat"; - -(*** Distinctness of constructors ***) - -Goalw [Zero_nat_def,Suc_def] "Suc(m) ~= 0"; -by (rtac (inj_on_Abs_Nat RS inj_on_contraD) 1); -by (rtac Suc_Rep_not_Zero_Rep 1); -by (REPEAT (resolve_tac [Rep_Nat, rew Nat'.Suc_RepI, rew Nat'.Zero_RepI] 1)); -qed "Suc_not_Zero"; - -bind_thm ("Zero_not_Suc", Suc_not_Zero RS not_sym); - -AddIffs [Suc_not_Zero,Zero_not_Suc]; - -bind_thm ("Suc_neq_Zero", (Suc_not_Zero RS notE)); -bind_thm ("Zero_neq_Suc", sym RS Suc_neq_Zero); - -(** Injectiveness of Suc **) - -Goalw [Suc_def] "inj(Suc)"; -by (rtac injI 1); -by (dtac (inj_on_Abs_Nat RS inj_onD) 1); -by (REPEAT (resolve_tac [Rep_Nat, rew Nat'.Suc_RepI] 1)); -by (dtac (inj_Suc_Rep RS injD) 1); -by (etac (inj_Rep_Nat RS injD) 1); -qed "inj_Suc"; - -bind_thm ("Suc_inject", inj_Suc RS injD); - -Goal "(Suc(m)=Suc(n)) = (m=n)"; -by (EVERY1 [rtac iffI, etac Suc_inject, etac arg_cong]); -qed "Suc_Suc_eq"; - -AddIffs [Suc_Suc_eq]; - -Goal "n ~= Suc(n)"; -by (nat_ind_tac "n" 1); -by (ALLGOALS Asm_simp_tac); -qed "n_not_Suc_n"; - -bind_thm ("Suc_n_not_n", n_not_Suc_n RS not_sym); - -Goal "(ALL x. x = (0::nat)) = False"; -by Auto_tac; -qed "nat_not_singleton"; - -(*** Basic properties of "less than" ***) - -Goalw [wf_def, pred_nat_def] "wf pred_nat"; -by (Clarify_tac 1); -by (nat_ind_tac "x" 1); -by (ALLGOALS Blast_tac); -qed "wf_pred_nat"; - -Goalw [less_def] "wf {(x,y::nat). x i<(k::nat)"; -by (rtac (trans_trancl RS transD) 1); -by (assume_tac 1); -by (assume_tac 1); -qed "less_trans"; - -Goalw [less_def, pred_nat_def] "n < Suc(n)"; -by (simp_tac (simpset() addsimps [r_into_trancl]) 1); -qed "lessI"; -AddIffs [lessI]; - -(* i i ~ m<(n::nat)"; -by (blast_tac (claset() addIs [wf_pred_nat, wf_trancl RS wf_asym])1); -qed "less_not_sym"; - -(* [| n m P *) -bind_thm ("less_asym", less_not_sym RS contrapos_np); - -Goalw [less_def] "~ n<(n::nat)"; -by (rtac (wf_pred_nat RS wf_trancl RS wf_not_refl) 1); -qed "less_not_refl"; - -(* n R *) -bind_thm ("less_irrefl", less_not_refl RS notE); -AddSEs [less_irrefl]; - -Goal "n m ~= (n::nat)"; -by (Blast_tac 1); -qed "less_not_refl2"; - -(* s < t ==> s ~= t *) -bind_thm ("less_not_refl3", less_not_refl2 RS not_sym); - - -val major::prems = Goalw [less_def, pred_nat_def] - "[| i P; !!j. [| i P \ -\ |] ==> P"; -by (rtac (major RS tranclE) 1); -by (ALLGOALS Full_simp_tac); -by (REPEAT_FIRST (bound_hyp_subst_tac ORELSE' - eresolve_tac (prems@[asm_rl, Pair_inject]))); -qed "lessE"; - -Goal "~ n < (0::nat)"; -by (blast_tac (claset() addEs [lessE]) 1); -qed "not_less0"; -AddIffs [not_less0]; - -(* n<0 ==> R *) -bind_thm ("less_zeroE", not_less0 RS notE); - -val [major,less,eq] = Goal - "[| m < Suc(n); m P; m=n ==> P |] ==> P"; -by (rtac (major RS lessE) 1); -by (rtac eq 1); -by (Blast_tac 1); -by (rtac less 1); -by (Blast_tac 1); -qed "less_SucE"; - -Goal "(m < Suc(n)) = (m < n | m = n)"; -by (blast_tac (claset() addSEs [less_SucE] addIs [less_trans]) 1); -qed "less_Suc_eq"; - -Goal "(n < (1::nat)) = (n = 0)"; -by (simp_tac (simpset() addsimps [less_Suc_eq]) 1); -qed "less_one"; -AddIffs [less_one]; - -Goal "(n < Suc 0) = (n = 0)"; -by (simp_tac (simpset() addsimps [less_Suc_eq]) 1); -qed "less_Suc0"; -AddIffs [less_Suc0]; - -Goal "m Suc(m) < Suc(n)"; -by (etac rev_mp 1); -by (nat_ind_tac "n" 1); -by (ALLGOALS (fast_tac (claset() addEs [less_trans, lessE]))); -qed "Suc_mono"; - -(*"Less than" is a linear ordering*) -Goal "m P n m; m=n ==> P n m; n P n m |] ==> P n m"; -by (rtac (less_linear RS disjE) 1); -by (etac disjE 2); -by (etac lessCase 1); -by (etac (sym RS eqCase) 1); -by (etac major 1); -qed "nat_less_cases"; - - -(** Inductive (?) properties **) - -Goal "[| m Suc(m) < n"; -by (full_simp_tac (simpset() addsimps [nat_neq_iff]) 1); -by (blast_tac (claset() addSEs [less_irrefl, less_SucE] addEs [less_asym]) 1); -qed "Suc_lessI"; - -Goal "Suc(m) < n ==> m P \ -\ |] ==> P"; -by (rtac (major RS lessE) 1); -by (etac (lessI RS minor) 1); -by (etac (Suc_lessD RS minor) 1); -by (assume_tac 1); -qed "Suc_lessE"; - -Goal "Suc(m) < Suc(n) ==> m j Suc i < k"; -by (nat_ind_tac "k" 1); -by (ALLGOALS (asm_simp_tac (simpset()))); -by (asm_simp_tac (simpset() addsimps [less_Suc_eq]) 1); -by (blast_tac (claset() addDs [Suc_lessD]) 1); -qed_spec_mp "less_trans_Suc"; - -(*Can be used with less_Suc_eq to get n=m | n P(m) |] ==> P(n) |] ==> P(n)"; -by (wf_ind_tac "n" [wf_pred_nat RS wf_trancl] 1); -by (eresolve_tac prems 1); -qed "nat_less_induct"; - -(*** Properties of <= ***) - -(*Was le_eq_less_Suc, but this orientation is more useful*) -Goalw [le_def] "(m < Suc n) = (m <= n)"; -by (rtac (not_less_eq RS sym) 1); -qed "less_Suc_eq_le"; - -(* m<=n ==> m < Suc n *) -bind_thm ("le_imp_less_Suc", less_Suc_eq_le RS iffD2); - -Goalw [le_def] "(0::nat) <= n"; -by (rtac not_less0 1); -qed "le0"; -AddIffs [le0]; - -Goalw [le_def] "~ Suc n <= n"; -by (Simp_tac 1); -qed "Suc_n_not_le_n"; - -Goalw [le_def] "!!i::nat. (i <= 0) = (i = 0)"; -by (nat_ind_tac "i" 1); -by (ALLGOALS Asm_simp_tac); -qed "le_0_eq"; -AddIffs [le_0_eq]; - -Goal "(m <= Suc(n)) = (m<=n | m = Suc n)"; -by (simp_tac (simpset() delsimps [less_Suc_eq_le] - addsimps [less_Suc_eq_le RS sym, less_Suc_eq]) 1); -qed "le_Suc_eq"; - -(* [| m <= Suc n; m <= n ==> R; m = Suc n ==> R |] ==> R *) -bind_thm ("le_SucE", le_Suc_eq RS iffD1 RS disjE); - -Goalw [le_def] "~n m<=(n::nat)"; -by (assume_tac 1); -qed "leI"; - -Goalw [le_def] "m<=n ==> ~ n < (m::nat)"; -by (assume_tac 1); -qed "leD"; - -bind_thm ("leE", make_elim leD); - -Goal "(~n n<(m::nat)"; -by (Blast_tac 1); -qed "not_leE"; - -Goalw [le_def] "(~n<=m) = (m<(n::nat))"; -by (Simp_tac 1); -qed "not_le_iff_less"; - -Goalw [le_def] "m < n ==> Suc(m) <= n"; -by (simp_tac (simpset() addsimps [less_Suc_eq]) 1); -by (blast_tac (claset() addSEs [less_irrefl,less_asym]) 1); -qed "Suc_leI"; (*formerly called lessD*) - -Goalw [le_def] "Suc(m) <= n ==> m <= n"; -by (asm_full_simp_tac (simpset() addsimps [less_Suc_eq]) 1); -qed "Suc_leD"; - -(* stronger version of Suc_leD *) -Goalw [le_def] "Suc m <= n ==> m < n"; -by (asm_full_simp_tac (simpset() addsimps [less_Suc_eq]) 1); -by (cut_facts_tac [less_linear] 1); -by (Blast_tac 1); -qed "Suc_le_lessD"; - -Goal "(Suc m <= n) = (m < n)"; -by (blast_tac (claset() addIs [Suc_leI, Suc_le_lessD]) 1); -qed "Suc_le_eq"; - -Goalw [le_def] "m <= n ==> m <= Suc n"; -by (blast_tac (claset() addDs [Suc_lessD]) 1); -qed "le_SucI"; - -(*bind_thm ("le_Suc", not_Suc_n_less_n RS leI);*) - -Goalw [le_def] "m < n ==> m <= (n::nat)"; -by (blast_tac (claset() addEs [less_asym]) 1); -qed "less_imp_le"; - -(*For instance, (Suc m < Suc n) = (Suc m <= n) = (m m < n | m=(n::nat)"; -by (cut_facts_tac [less_linear] 1); -by (blast_tac (claset() addEs [less_irrefl,less_asym]) 1); -qed "le_imp_less_or_eq"; - -Goalw [le_def] "m m <=(n::nat)"; -by (cut_facts_tac [less_linear] 1); -by (blast_tac (claset() addSEs [less_irrefl] addEs [less_asym]) 1); -qed "less_or_eq_imp_le"; - -Goal "(m <= (n::nat)) = (m < n | m=n)"; -by (REPEAT(ares_tac [iffI,less_or_eq_imp_le,le_imp_less_or_eq] 1)); -qed "le_eq_less_or_eq"; - -(*Useful with Blast_tac. m=n ==> m<=n *) -bind_thm ("eq_imp_le", disjI2 RS less_or_eq_imp_le); - -Goal "n <= (n::nat)"; -by (simp_tac (simpset() addsimps [le_eq_less_or_eq]) 1); -qed "le_refl"; - - -Goal "[| i <= j; j < k |] ==> i < (k::nat)"; -by (blast_tac (claset() addSDs [le_imp_less_or_eq] - addIs [less_trans]) 1); -qed "le_less_trans"; - -Goal "[| i < j; j <= k |] ==> i < (k::nat)"; -by (blast_tac (claset() addSDs [le_imp_less_or_eq] - addIs [less_trans]) 1); -qed "less_le_trans"; - -Goal "[| i <= j; j <= k |] ==> i <= (k::nat)"; -by (blast_tac (claset() addSDs [le_imp_less_or_eq] - addIs [less_or_eq_imp_le, less_trans]) 1); -qed "le_trans"; - -Goal "[| m <= n; n <= m |] ==> m = (n::nat)"; -(*order_less_irrefl could make this proof fail*) -by (blast_tac (claset() addSDs [le_imp_less_or_eq] - addSEs [less_irrefl] addEs [less_asym]) 1); -qed "le_anti_sym"; - -Goal "(Suc(n) <= Suc(m)) = (n <= m)"; -by (simp_tac (simpset() addsimps le_simps) 1); -qed "Suc_le_mono"; - -AddIffs [Suc_le_mono]; - -(* Axiom 'order_less_le' of class 'order': *) -Goal "((m::nat) < n) = (m <= n & m ~= n)"; -by (simp_tac (simpset() addsimps [le_def, nat_neq_iff]) 1); -by (blast_tac (claset() addSEs [less_asym]) 1); -qed "nat_less_le"; - -(* [| m <= n; m ~= n |] ==> m < n *) -bind_thm ("le_neq_implies_less", [nat_less_le, conjI] MRS iffD2); - -(* Axiom 'linorder_linear' of class 'linorder': *) -Goal "(m::nat) <= n | n <= m"; -by (simp_tac (simpset() addsimps [le_eq_less_or_eq]) 1); -by (cut_facts_tac [less_linear] 1); -by (Blast_tac 1); -qed "nat_le_linear"; - -Goal "~ n < m ==> (n < Suc m) = (n = m)"; -by (blast_tac (claset() addSEs [less_SucE]) 1); -qed "not_less_less_Suc_eq"; - - -(*Rewrite (n < Suc m) to (n=m) if ~ n